繁体   English   中英

通过 javascript 将数组转换为 json object

[英]Convert an array to json object by javascript

我坚持要解决这个问题。 转换下面的数组

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

至 json Object

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

我可以申请哪种数据结构和算法? 谢谢

您需要先split每个元素以转换为数组

使用reverse reduce方法,您可以将它们转换为 object。

最后一步是合并这些对象。

Lodash.js合并方法是合并它们的一种方法。

 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.com/ajax/libs/lodash.js/4.17.10/lodash.js"></script>

为了使过程更易于理解,请将问题分解为多个部分。

第一步是将每个字符串转换为我们可以使用的东西,将其转换为:

"animal/mammal/dog"

进入这个:

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

这是构建最终 object 所需的一组属性名称。

两个函数将为您完成此操作, String.prototype.split()将字符串拆分为数组, Array.prototype.map()转换每个数组元素:

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

中间结果是这样的:

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

下一步是遍历每个数组,使用Array.prototype.forEach()将属性添加到 object。 您可以使用 for 循环向 object 添加属性,但让我们使用递归 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);
});

结果:

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

您可以创建一个 function,它将数组中的每个元素按“/”切片,而不是将结果放入变量中,而不仅仅是安装 Json。 我的意思是这样的:


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

派对迟到了,这是我的尝试。 我正在实现recursive方法:

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

我尝试使用数组减少,希望对您有所帮助

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM