从对象数组创建树状json对象

时间:2018-04-24 09:38:21

标签: javascript arrays object tree

我是javascript对象和树创建的初学者,所以请耐心等待。 我有一个像这样的对象数组

[
    {
        "l1": 1,
        "l2": 2,
        "l3": 3,
        "l4": 4,
        "l5": 5,
        "l6": null
    },
    {
        "l1": 1,
        "l2": 2,
        "l3": 3,
        "l4": 4,
        "l5": 6,
        "l6": null
    },
    {
        "l1": 1,
        "l2": 2,
        "l3": 7,
        "l4": 8,
        "l5": 9,
        "l6": null
    },
    {
        "l1": 1,
        "l2": 2,
        "l3": 7,
        "l4": 8,
        "l5": 10,
        "l6": null
    },
    {
        "l1": 1,
        "l2": 2,
        "l3": 3,
        "l4": 11,
        "l5": 12,
        "l6": null
    },
    {
        "l1": 1,
        "l2": 2,
        "l3": 3,
        "l4": 11,
        "l5": 13,
        "l6": null
    }
]

我已将此数据存储在json文件中,并且我想使用此对象数组创建类似树结构的对象。这样的事情。

{
  "1": [
    {
      "2": [
        {
          "3": [
            {
              "4": [
                {
                  "5": [
                    null
                  ]
                },
                {
                  "6": [
                    null
                  ]
                }
              ]
            },
            {
              "11": [
                {
                  "12": [
                    null
                  ]
                },
                {
                  "13": [
                    null
                  ]
                }
              ]
            }
          ]
        },
        {
          "7": [
            {
              "8": [
                {
                  "9": [
                    null
                  ]
                },
                {
                  "10": [
                    null
                  ]
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

我试图自己做这件事,但我一开始就失败了。

这是我的尝试

var fs = require('fs');
var file = 'levels.json';
var content = fs.readFileSync(file, { encoding: 'binary' });
var obj = {}
JSON.parse(content).forEach((curr, i, arr)=>{
    if(curr.l1){
        obj[curr.l1] = []
    }
    if(curr.l2){
        var l2obj = {}
        l2obj[curr.l2] = []
        obj[curr.l1].push(l2obj)
        // obj[curr.l1].push({curr.l2:[]})
    }
})

fs.writeFileSync('theObject.json', JSON.stringify(obj), 'utf8');

我发现的问题是,行l2obj[curr.l2] = []正在覆盖前一个数组,我无法正确嵌套它们。行obj[curr.l1] = []存在一个问题。我也尝试了注释行,但它引发了语法错误。我觉得它非常基本但也很混乱,我如何从动态值创建对象并将它们推送到数组而不会覆盖前一个数组。任何建议,提示。
第二行问题,这是表示这样的数据的最佳方式吗?我想使用树结构,因为它看起来像是一种准确和最短的数据结构形式.json数据有近20k个具有级别信息的对象。建议得到高度赞赏。

2 个答案:

答案 0 :(得分:1)

您可以先构建一个不同的嵌套结构,不使用数组,然后使用其他递归函数迭代该数据并更改它所需的输出。



const data =[{"l1":1,"l2":2,"l3":3,"l4":4,"l5":5,"l6":null},{"l1":1,"l2":2,"l3":3,"l4":4,"l5":6,"l6":null},{"l1":1,"l2":2,"l3":7,"l4":8,"l5":9,"l6":null},{"l1":1,"l2":2,"l3":7,"l4":8,"l5":10,"l6":null},{"l1":1,"l2":2,"l3":3,"l4":11,"l5":12,"l6":null},{"l1":1,"l2":2,"l3":3,"l4":11,"l5":13,"l6":null}]
const result = {}

data.forEach(o => {
  Object.keys(o).reduce((r, e, i, arr) => {
    const key = o[e];
    if (o[e] == null) return r;
    if (o[arr[i + 1]] == null) r[key] = null
    else if (!r[key]) r[key] = {}
    return r[key]
  }, result)
})

function build(input) {
  for (let key in input) {
    if (input[key] && Object.keys(input[key]).length) build(input[key]);
    input[key] = [input[key]]
  }
}

build(result)

console.log(result)




更新:你也可以使用这样的对象获得嵌套结构。



const data =[{"l1":1,"l2":2,"l3":3,"l4":4,"l5":5,"l6":null},{"l1":1,"l2":2,"l3":3,"l4":4,"l5":6,"l6":null},{"l1":1,"l2":2,"l3":7,"l4":8,"l5":9,"l6":null},{"l1":1,"l2":2,"l3":7,"l4":8,"l5":10,"l6":null},{"l1":1,"l2":2,"l3":3,"l4":11,"l5":12,"l6":null},{"l1":1,"l2":2,"l3":3,"l4":11,"l5":13,"l6":null}]
const result = {}

data.forEach(o => {
  Object.keys(o).reduce((r, e) => {
    if (o[e] == null) return r;
    return r[o[e]] = (r[o[e]] || {})
  }, result)
})

console.log(result)




答案 1 :(得分:0)

我想出来了,我不得不改变结果的格式,而不是数组我使用了对象格式本身。我意识到阵列数据结构正在打败我的目的。 所以我真正想要的结果是

{
  "1": {
    "2": {
      "3": {
        "4": {
          "5": {},
          "6": {}
        },
        "11": {
          "12": {},
          "13": {}
        }
      },
      "7": {
        "8": {
          "9": {},
          "10": {}
        }
      }
    }
  }
}

解决方案看起来很奇怪,但很容易理解,我正在运行6次传递来创建嵌套对象。

var data = JSON.parse(content)
data.forEach((curr, i, arr)=>{
    if(curr.l1){
        obj[curr.l1] = {}
    }
})
data.forEach((curr, i, arr)=>{
    if(curr.l2 ){            
        obj[curr.l1][curr.l2] = {}
    }
})
data.forEach((curr, i, arr)=>{
    if(curr.l3 ){            
        obj[curr.l1][curr.l2][curr.l3] = {}
    }
})
data.forEach((curr, i, arr)=>{
    if(curr.l4 ){            
        obj[curr.l1][curr.l2][curr.l3][curr.l4] = {}
    }
})
data.forEach((curr, i, arr)=>{
    if(curr.l5 ){            
        obj[curr.l1][curr.l2][curr.l3][curr.l4][curr.l5] = {}
    }
})
data.forEach((curr, i, arr)=>{
    if(curr.l6 ){            
        obj[curr.l1][curr.l2][curr.l3][curr.l4][curr.l5][curr.l6] = {}
    }
})