![](/img/trans.png)
[英]Create a nested array of objects (up to 5 levels) from flat array of objects
[英]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))
您可以通過使用對象和id
和parent_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.