Converting an array to a JSON object using JavaScript

I need help with converting the following array into a JSON object:

var input = [
    'animal/mammal/dog',
    'animal/mammal/cat/tiger',
    'animal/mammal/cat/lion',
    'animal/mammal/elephant',
    'animal/reptile',
    'plant/sunflower'
]

The desired output is as follows:

var expectedResult = {
 "animal": {
  "mammal": {
   "dog": true,
   "cat": {
    "tiger": true,
    "lion": true
   },
   "elephant": true
  },
  "reptile": true
 },
 "plant": {
  "sunflower": true
 }
}

What data structure and algorithm would be best suited for this task? Thank you!

Answer №1

To begin, you must first separate each element to transform them into arrays.

By utilizing the reverse and reduce methods, you can convert these arrays into objects.

Lastly, your task is to merge these objects together.

The Lodash.js merge method provides a convenient way to achieve this.

var entries = ['animal/mammal/dog','animal/mammal/cat/tiger','animal/mammal/cat/lion', 'animal/mammal/elephant','animal/reptile', 'plant/sunflower']
var resultByLodash={}
entries.forEach(entry=>{
  const keys = entry.split("/");
  const output = keys.reverse().reduce((res, key) => ({[key]: res}), true);
  resultByLodash = _.merge({}, resultByLodash, output);
});
console.log(resultByLodash);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.js"></script>

Answer №2

Break down the problem into manageable pieces for better understanding of the process.

Start by converting each string into a usable format, like this:

"animal/mammal/dog"

which becomes:

[ "animal", "mammal", "dog" ]

This array represents the property names required to construct the final object.

You can achieve this with two functions: String.prototype.split() to split the string into an array and Array.prototype.map() to transform each element of the array:

let splitIntoNames = input.map(str => str.split('/'));

The resulting intermediate array looks like this:

[
  [ "animal", "mammal", "dog" ],
  [ "animal", "mammal", "cat", "tiger" ],
  [ "animal", "mammal", "cat", "lion" ],
  [ "animal", "mammal", "elephant" ],
  [ "animal", "reptile" ],
  [ "plant", "sunflower" ]
]

Next, iterate over each array using Array.prototype.forEach() to add properties to the object. While you could use a for loop to add properties, let's do it recursively with a function called addName():

function addName(element, list, index) {
  if (index >= list.length) {
    return;
  }
  let name = list[index];
  let isEndOfList = index === list.length - 1;

  element[name] = element[name] || (isEndOfList ? true : {});

  addName(element[name], list, index + 1);
}

let result = {};
splitIntoNames.forEach(list => {
  addName(result, list, 0);
});

The final result is:

result: {
  "animal": {
    "mammal": {
      "dog": true,
      "cat": {
        "tiger": true,
        "lion": true
      },
      "elephant": true
    },
    "reptile": true
  },
  "plant": {
    "sunflower": true
  }
}

const input = [
  "animal/mammal/dog",
  "animal/mammal/cat/tiger",
  "animal/mammal/cat/lion",
  "animal/mammal/elephant",
  "animal/reptile",
  "plant/sunflower",
];

let splitIntoNames = input.map(str => str.split("/"));
console.log("splitIntoNames:", JSON.stringify(splitIntoNames, null, 2));

function addName(element, list, index) {
  if (index >= list.length) {
    return;
  }
  let name = list[index];
  let isEndOfList = index === list.length - 1;

  element[name] = element[name] || (isEndOfList ? true : {});

  addName(element[name], list, index + 1);
}

let result = {};
splitIntoNames.forEach(list => {
  addName(result, list, 0);
});
console.log("result:", JSON.stringify(result, null, 2));

Answer №3

To streamline the array elements, you can devise a function that splits them by "/", save the outcomes in a variable, and then construct the Json accordingly. Here is a concept to illustrate this:


    window.onload = function() {
      var finalResult;
      var input = [
        'animal/mammal/dog',
        'animal/mammal/cat/tiger',
        'animal/mammal/cat/lion',
        'animal/mammal/elephant',
        'animal/reptile',
        'plant/sunflower'
    ]

      input.forEach(element => {
        var data = element.split('/');

        var dog = data[2] === 'dog' ? true : false
        var tiger = data[2] === 'cat' && data[3] === 'tiger'  ? true : false
        var lion = data[2] === 'cat' && data[3] === 'lion'  ? true : false


        finalResult = {
          data[0]: {
            data[1]: {
             "dog": dog,
             "cat": {
              "tiger": tiger,
              "lion": lion
             }
            }
          }
        }
      })
    }

Answer №4

Joining the conversation a bit late, here is my attempt at solving the problem. My approach involves using recursion:

var input = ['animal/mammal/dog', 'animal/mammal/cat/tiger', 'animal/mammal/cat/lion', 'animal/mammal/elephant', 'animal/reptile', 'plant/sunflower'];

result = (buildObject = (array, object = {}) => {
  array.forEach((value) => {
    keys = value.split('/');
    (nestedFunction = (obj) => {
      currentKey = keys.shift();
      obj[currentKey] = obj[currentKey] || {};
      if (keys.length == 0) obj[currentKey] = true;
      if (keys.length > 0) nestedFunction(obj[currentKey]);
    })(object)
  })
  return object;
})(input);

console.log(result);

Answer №5

I utilized array reduce method to tackle this issue

let data = [
  "animal/mammal/dog",
  "animal/mammal/cat/tiger",
  "animal/mammal/cat/lion",
  "animal/elephant",
  "animal/reptile",
  "plant/sunflower",
];

let processInput = (i = []) =>
  i.reduce((previous, currentItem = "") => {
    let point = previous;
    currentItem.split("/").reduce((prevPre, currentPre, preIndex, arrPrev) => {
      if (!point[currentPre]) {
        point[currPre] = preIndex === arrPrev.length - 1 ? true : {};
      }
      point = point[curentPre];
    }, {});
    return previous;
  }, {});

console.log(JSON.stringify(processInput(data), null, 4));

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Performing a password-protected JavaScript Ajax request that includes special characters

Within my JavaScript page, I have implemented an Ajax call shown in the code snippet below. The PHP page resides within a corporate intranet that demands domain authentication (without basic auth). To extract the username (u) and password (p), I am using j ...

Are these objects enclosed within a JavaScript array?

Are square brackets used to define arrays and curly brackets used for objects? Can you explain the following data structure: Some.thing = [ { "swatch_src" : "/images/91388044000.jpg", "color" : "black multi", "inventory" : { "F" : [ 797113, 797 ...

Setting intervals to change background images resulted in a delay

I've been working on creating an animation that switches between 2 images used as the background image of a div. Here's the code snippet I've been using: var spacecraftInterval = setInterval(function() { if (access == true) { var image ...

Store data in Firebase Storage and retrieve the link to include it in Realtime Database

Utilizing Firebase Realtime Database and Firebase Storage for this application involves uploading images from the pictures array to Firebase Storage. The goal is to obtain the Firebase Storage link for each image, add it to the object pushed into imagesU ...

Error: Unable to iterate over data.data due to its type

I am attempting to fetch images from the woocommerce API and here is the code I am using: this.config.getWithUrl(this.config.url + '/api/appsettings/get_all_banners/?insecure=cool') .then((data: any) => { this.banners = data.data; consol ...

Bind AngularJS data to select elements

I am encountering an issue with data binding on a select tag, despite following the guidelines in the documentation. Here is my select element: <select id="start-type" ng-model="startType"> <option value="day-of-week">Day of the week</op ...

Guide on inserting text within a Toggle Switch Component using React

Is there a way to insert text inside a Switch component in ReactJS? Specifically, I'm looking to add the text EN and PT within the Switch Component. I opted not to use any libraries for this. Instead, I crafted the component solely using CSS to achie ...

Passing a particular object from an array of objects as props in React Native

Suppose you have a static array consisting of 4 objects and the goal is to pass specific data items from the third object in this array. How can this task be accomplished? Let's consider an example: const ENTRIES = [ { name: "John" color: "#fffff" f ...

What steps should I take to ensure my three.js project is compatible with iPhone testing?

I recently developed a new AR project that allows users to interact with AR content through their phone camera on a website. However, I am facing an issue where I cannot easily test my website on an iPhone whenever I make changes to the code. Currently, ...

Verifying JSON Schema in Java: Ensuring Data Integrity

Back in 2019-09, I developed a JSON Schema (). Does anyone know how to validate it using Java? I need assistance creating a method that will throw an Exception if the validation fails: void validate(Path pathToSchema) throws Exception { // Validate sch ...

Array with multiple dimensions using commas as delimiters

My array (array[]) contains elements in the format below, separated by a comma: array[0] = abc, def, 123, ghi I want to transform this array into another multi-dimensional array (arrayTwo[]), structured like this: arrayTwo[0][0] = "abc" arrayTwo[0][1] = ...

Revamping JSON structure by identifying id references

I recently attempted to update the city name within the JSON object provided below. "City":[ { "Name":"Delhi", "id":"c5d58bef-f1c2-4b7c-a6d7-f64df12321bd", "Towns":[ ...

Incorporating jQuery to seamlessly add elements without causing any disruptions to the layout

I'm looking to enhance the design of my website by adding a mouseenter function to display two lines when hovering over an item. However, I've encountered an issue where the appearance and disappearance of these lines cause the list items to move ...

Tips for concealing the check mark within a checkbox upon selection

I have checkboxes arranged in a table with 23 columns and 7 rows. My goal is to style the checkboxes in a way that hides the check mark when selected. I also want to change the background image of the checkbox to fill it with color when marked. Can someone ...

Achieving functionality with dropdown menus in jQuery

I am facing an issue with a dropdown menu that works perfectly in jsFiddle during testing, but does not function as expected when I run it on my testing server. jsFiddle: http://jsfiddle.net/cyberjo50/39bu8/2/ HTML <!doctype html> <html> < ...

Why is my Ajax utilizing PHP _POST not functioning as expected?

I am facing an issue with the JavaScript code below: <script src='https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js'></script> <script> function deletUserInfo(id_user){ console.log(id_user); ...

How can I utilize the mapping function on a promise received from fetch and display it on the page using React

As I'm using fetch to return a promise, everything is working fine. However, I am facing an issue while trying to map over the fetched data. When I check my console log, it shows "undefined." const dataPromise = fetch('http://api.tvmaze.com/sche ...

Omit any NULL Hateoas "links" in the spring boot RESTful API reply

When I use a sample response class that extends RepresentationModel, sometimes I do not include any hateoas links in the response. This results in having an empty "links" field in the JSON response. "links": [] I attempted to use "JsonInc ...

Retrieve a particular HTML element from an object that has been mapped

After reproducing my issue on a smaller scale for easier handling, I am now aiming to implement an onclick function that reveals the hidden content inside each column. The plan is to initially hide the content using display: none and then switch it to disp ...

Using the splice() method to remove an item from an array may cause unexpected results in React applications

Dynamic input fields are being created based on the number of objects in the state array. Each field is accompanied by a button to remove it, but there seems to be unexpected behavior when the button is clicked. A visual demonstration is provided below: ...