簡體   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