从对象数组创建嵌套数组数据

时间:2018-11-20 15:21:48

标签: javascript arrays json

我有一个具有嵌套数据信息的对象数组,我想将数据转换为实际的嵌套数组数据。 我该如何转换:

const data = [
  {id: 1, parent_id: null, name: 'test1'},
  {id: 2, parent_id: null, name: 'test2'},
  {id: 3, parent_id: 2, name: 'test3'},
  {id: 4, parent_id: 2, name: 'test4'},
  {id: 5, parent_id: 4, name: 'test5'},
  {id: 6, parent_id: 4, name: 'test5'},
  {id: 7, parent_id: 2, name: 'test5'},
  {id: 8, parent_id: 2, name: 'test5'},
  {id: 9, parent_id: null, name: 'test5'},
  {id: 10, parent_id: null, name: 'test5'},
]

对此:

const data = [
  {id: 1, parent_id: null, name: 'test1'},
  {
    id: 2, 
    parent_id: null, 
    name: 'test2',
    children: [
      {id: 3, parent_id: 2, name: 'test3'},
      {
        id: 4, 
        parent_id: 2, 
        name: 'test4',
        children: [
          {id: 5, parent_id: 4, name: 'test5'},
          {id: 6, parent_id: 4, name: 'test5'}
        ]
      },
      {id: 7, parent_id: 2, name: 'test5'},
      {id: 8, parent_id: 2, name: 'test5'},
    ]
  },
  {id: 9, parent_id: null, name: 'test5'},
  {id: 10, parent_id: null, name: 'test5'},
]

最好的方法是什么?

5 个答案:

答案 0 :(得分:3)

您可以为此使用{ "openapi": "3.0.0", "info": { "title": "Demo API", "description": "This is a basic REST API implementing the [Open API Specification](https://en.wikipedia.org/wiki/OpenAPI_Specification).", "version": "0.0.1" }, # Schema definition goes here } 方法创建递归函数。

reduce

答案 1 :(得分:2)

您可以采用单循环方法,方法是使用一个对象以及idparent_id作为键并为其收集项目/子项。

顺序仅对children数组中的顺序很重要。

const
    data = [{ id: 1, parent_id: null, name: 'test1' }, { id: 2, parent_id: null, name: 'test2' }, { id: 3, parent_id: 2, name: 'test3' }, { id: 4, parent_id: 2, name: 'test4' }, { id: 5, parent_id: 4, name: 'test5' }, { id: 6, parent_id: 4, name: 'test5' }, { id: 7, parent_id: 2, name: 'test5' }, { id: 8, parent_id: 2, name: 'test5' }, { id: 9, parent_id: null, name: 'test5' }, { id: 10, parent_id: null, name: 'test5' }],
    tree = function (data, root) {
        var o = {};
        data.forEach(function (a) {
            Object.assign(o[a.id] = o[a.id] || {}, a, o[a.id] && o[a.id].children && { children: o[a.id].children });
            o[a.parent_id] = o[a.parent_id] || {};
            o[a.parent_id].children = o[a.parent_id].children || [];
            o[a.parent_id].children.push(o[a.id]);
        });
        return o[root].children;
    }(data, null);

console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 2 :(得分:0)

这是一个有趣的问题。如果您想保持线性时间以牺牲一些空间为代价,则可以选择一种方法来基于id来创建查找对象。然后,您可以遍历这些值并推入父对象或数组中:

const data = [{id: 1, parent_id: null, name: 'test1'},{id: 2, parent_id: null, name: 'test2'},{id: 3, parent_id: 2, name: 'test3'},{id: 4, parent_id: 2, name: 'test4'},{id: 5, parent_id: 4, name: 'test5'},{id: 6, parent_id: 4, name: 'test5'},{id: 7, parent_id: 2, name: 'test5'},{id: 8, parent_id: 2, name: 'test5'},{id: 9, parent_id: null, name: 'test5'},{id: 10, parent_id: null, name: 'test5'},]

let lookup = data.reduce((obj, item) => {
  obj[item.id] = item
  return obj
}, {})

let arr = Object.values(lookup).reduce((arr, val) =>{
  if (val.parent_id == null) arr.push(val)
  else (lookup[val.parent_id].children || ( lookup[val.parent_id].children = [])).push(val)
  
  return arr
}, [])

console.log(JSON.stringify(arr, null, 2))

答案 3 :(得分:0)

您可以尝试这种递归方法

forEach()

答案 4 :(得分:-1)

const data = [
  {id: 1, parent_id: null, name: 'test1'},
  {id: 2, parent_id: null, name: 'test2'},
  {id: 3, parent_id: 2, name: 'test3'},
  {id: 4, parent_id: 2, name: 'test4'},
  {id: 5, parent_id: 4, name: 'test5'},
  {id: 6, parent_id: 4, name: 'test5'},
  {id: 7, parent_id: 2, name: 'test5'},
  {id: 8, parent_id: 2, name: 'test5'},
  {id: 9, parent_id: null, name: 'test5'},
  {id: 10, parent_id: null, name: 'test5'},
]

const output = data.filter(
  item => !item.parent_id
).map(
  rootItem => ({
    ...rootItem,
    children: data.filter(item => item.parent_id === rootItem.id),
  })
)

console.log(output)