繁体   English   中英

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

[英]Create nested array data from an array of objects

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

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'},
]

做这个的最好方式是什么?

您可以为此使用reduce方法创建递归函数。

 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'},] function nest(data, parentId = null) { return data.reduce((r, e) => { let obj = Object.assign({}, e) if (parentId == e.parent_id) { let children = nest(data, e.id) if (children.length) obj.children = children r.push(obj) } return r; }, []) } console.log(nest(data))

您可以通过使用对象和idparent_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' }], tree = function (data, root) { var t = {}; data.forEach(o => { Object.assign(t[o.id] = t[o.id] || {}, o); t[o.parent_id] = t[o.parent_id] || {}; t[o.parent_id].children = t[o.parent_id].children || []; t[o.parent_id].children.push(t[o.id]); }); return t[root].children; }(data, null); console.log(tree);
 .as-console-wrapper { max-height: 100% !important; top: 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))

你可以试试这种递归方法

 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 transform = arr => { return arr.reduce((acc, elem) => { const children = data.filter(el => el.parent_id === elem.id), isPresent = findDeep(acc, elem); if(!isPresent && children.length) acc.push({...elem, children: transform(children)}); else if(!isPresent) acc.push(elem); return acc; }, []); } const findDeep =(arr = [], elem) => ( arr.some(el => (el.id === elem.id) || findDeep(el.children, elem)) ); console.log(transform(data));

 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)

暂无
暂无

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

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