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

Encountering a [$injector:modulerr] error while attempting to include modules in ZURB Foundation for Apps

I am currently working on a project that involves specific authentication which is functioning well in Ionic. My task now is to incorporate the same authentication system into the admin panel exclusively for web devices. I have already completed the instal ...

The slash character is escaped by the RegExp constructor, but the dot character is

Consider the following code: console.log(new RegExp('.git')); console.log(new RegExp('scripts/npm')); which produces the following output: /.git/ /scripts\/npm/ The puzzling question here is - why does it escape the slash in &a ...

Looking to implement https requests in a phonegap app on an iPhone device?

Attempting to make an HTTPS request in a PhoneGap iPhone app using jQuery's getJSON() method is successful in the regular Safari browser. However, when attempting to do the same in Mobile Safari, an error message stating "Download Failed - Safari cann ...

Having difficulty updating the parent for all PortfolioItem/Feature that were copied for a specific PortfolioItem/MMF

I'm facing a challenge in setting the parent for multiple features that I've copied for a specific MMF. However, only the parent of the last feature is being set. Below is the code snippet responsible for setting the parent: Record represents th ...

Determine the total number of arrays present in the JSON data

I'm currently working on a straightforward AngularJS project, and here's the code I have so far: This is my view: <tr ng-repeat="metering in meterings"> <td>1</td> <td>{{metering.d.SerialNumber}}</td> ...

Tips on extracting the image URL after uploading via Google Picker

I'm currently implementing the Google Drive File Picker on my website for file uploading. Everything seems to be working well, except I am facing an issue with retrieving the image URL for images uploaded through the picker. Below is my current JavaSc ...

Error Alert: React Native object cannot be used as a React child within JSON, leading to an Invariant Violation

When using React-Native: To start, here is the example code of a json file: Any placeholders marked with "..." are for string values that are not relevant to the question. [ { "id": "question1" "label": "..." "option": [ { "order": 1, "name": "..."}, ...

Initiate Child Event within Parent Component

Before switching tabs in the parent component, I want the child tab to validate itself. My idea is to pass the onActive event from the parent to its children, <ClientInfo/> and <Details/>. This will allow the children to validate themselves a ...

Experimenting with TypeScript code using namespaces through jest (ts-jest) testing framework

Whenever I attempt to test TypeScript code: namespace MainNamespace { export class MainClass { public sum(a: number, b: number) : number { return a + b; } } } The test scenario is as follows: describe("main test", () ...

Utilize ReactJS and AJAX to easily upload images

Having trouble with uploading an image through a form to a url/api. When I submit the form, I'm calling the handleImgUpload() method. The issue is that the request being sent is coming back empty. Seems like there might be a problem with new FormData ...

Functionality that can be utilized repeatedly

I've been struggling to implement a feature for repeatable blocks in my web form. The issue I'm facing is that when I click the buttons, nothing happens even though they work fine when tested in the console. I've been stuck on this problem f ...

What is the best way to present a unique page overlay specifically for iPhone users?

When browsing WebMD on a computer, you'll see one page. However, if you access it from an iPhone, not only will you be directed to their mobile page (which is easy enough), but they also display a special overlay with a "click to close" button prompti ...

How to activate the menu in AngularJS

Within my application, I have a header that contains various menu items. These menu items are fetched from a service and displayed in the header. When hovering over the main list, the submenus appear. My goal is to highlight the parent item as active when ...

Ways to structure this updateone query for mongoose formatting

UPDATE: After making adjustments to the query using arrayFilters recommended by someone here, the query is returning success. However, the values in the database are not being updated. I am attempting to update specific fields within a MongoDB collection ...

The issue I am facing is that the string parameter is not functioning properly within

When creating a new build, I include a parameterized string called VERSION. Within the build, this command is present: sed -i -e 's/REPLACE_ME/$VERSION/g' config/config.json The configuration file in JSON format appears as follows: { "ENV": { ...

Is there a way to duplicate items similar to MS Word by using a combination of ctrl + mouse click +

In my fabricjs application, I currently clone an object by clicking ctrl + left mouse click on it, which works fine. However, I would like to be able to clone the object in a similar way to MS WORD, by using ctrl + click + drag. Has anyone achieved this f ...

Can a star rating be generated from a JSON value?

I'm curious if it's possible to display a glyphicon-star based on the value in a JSON file using AJAX. Here is an example of my JSON file: [ { "star": 4 },{ "star": 3 },{ "star": 5 } ] Here is my AJAX code: $(function($){ ...

Iterate through the list of objects and display duplicates only once

var fixtures = [ { "matchday": 1, "homeTeamName": "Arsenal FC", "awayTeamName": "Leicester City FC" }, { "matchday": 1, "homeTeamName": "AFC Bournemouth", ...

Open in a new tab for enhanced content formatting in Prismic on NextJs

In my Prismic RichText editor, I have included two files (terms and conditions) that I would like to open in a new tab. Unfortunately, Prismic does not offer an option like target _blank for this functionality. I am currently working with NextJs and Tail ...

Using angular.js variables in the script tag: A step-by-step guide

Currently, I am working on a project that involves displaying elements on a view using Angular.js and attempting to connect these DOM elements using jQuery connections. While the elements are being displayed correctly, I am encountering an issue when tryin ...