Convert an array to json object by javascript - Stack Overflow

I am stuck to solve this problem.Convert an array belowvar input = ['animalmammaldog',

I am stuck to solve this problem. Convert an array below

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

to json Object

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

Which data structure and algorithm can I apply for it? Thanks

I am stuck to solve this problem. Convert an array below

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

to json Object

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

Which data structure and algorithm can I apply for it? Thanks

Share Improve this question asked May 24, 2020 at 14:52 Le Duc AnhLe Duc Anh 1411 silver badge3 bronze badges 4
  • "json object"! you mean JavaScript object?! JSON is a format – phuzi Commented May 24, 2020 at 14:56
  • I mean that object has format like json. :) – Le Duc Anh Commented May 24, 2020 at 14:59
  • it does not, it's a plain javascript object. – PA. Commented May 24, 2020 at 15:10
  • you should read about iterating an string and creating an object and objects inside objects recursively, it is not as difficult as it sounds. – PA. Commented May 24, 2020 at 15:13
Add a ment  | 

5 Answers 5

Reset to default 4

You need to first split each element to convert to array

using reverse reduce method you can convert them to object.

And your last step is merge this objects.

Lodash.js merge method is an one way to merge them.

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

To make the process more understandable, break the problem down into pieces.

The first step is convert each string into something we can use, converting this:

"animal/mammal/dog"

into this:

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

That's an array of property names needed to build the final object.

Two functions will acplish this for you, String.prototype.split() to split the string into an array, and Array.prototype.map() to transform each of the array elements:

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

The intermediate result is this:

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

Next step is to iterate over each array, using Array.prototype.forEach() to add properties to the object. You could add properties to the object with a for loop, but let's do that with a recursive function 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 result:

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));

You can create a function that will slice every element from the array by "/" than you put the results into a variable and than just mount the Json. I mean something like that below:


    window.onload = function() {
      var expectedResult;
      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


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

Late to the party, here is my try. I'm implmenting recursive approach:

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

result = (buildObj = (array, Obj = {}) => {
  array.forEach((val) => {
    keys = val.split('/');
    (nestedFn = (object) => {
      outKey = keys.shift();
      object[outKey] = object[outKey] || {};
      if (keys.length == 0) object[outKey] = true;
      if (keys.length > 0) nestedFn(object[outKey]);
    })(Obj)
  })
  return Obj;
})(input);

console.log(result);

I try with array reduce, hope it help

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

let convertInput = (i = []) =>
  i.reduce((prev, currItem = "") => {
    let pointer = prev;
    currItem.split("/").reduce((prevPre, currPre, preIdx, arrPre) => {
      if (!pointer[currPre]) {
        pointer[currPre] = preIdx === arrPre.length - 1 ? true : {};
      }
      pointer = pointer[currPre];
    }, {});
    return prev;
  }, {});

console.log(JSON.stringify(convertInput(input), null, 4));

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744210731a4563320.html

相关推荐

  • Convert an array to json object by javascript - Stack Overflow

    I am stuck to solve this problem.Convert an array belowvar input = ['animalmammaldog',

    8天前
    10

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信