[英]How to flatten an object that has array of objects in Javascript
我正在嘗試解決這個問題,它需要我扁平化這個 object parent
,它有children
,每個父母都有 2 個孩子,每個孩子有 2 個孩子,依此類推....
我的目標是將其扁平化為一個 object。
const par = {
id: 1,
name: "parent",
children: [{
id: 2,
name: "child 1",
children:[{
id: 4,
name: "child 3",
children: [],
},{
id: 5,
name: "child 4 ",
}]
},{
id: 3,
name: "child 2",
children: [{
id: 6,
name: "child 5",
},{
id: 7,
name: "child 6",
children: []
}]
}]
}
我試過 function,但它遞歸地從Deep Flatten JavaScript Object返回一個數組
function flat(r, a) {
let b = {};
Object.keys(a).forEach(function (k) {
if (k !== 'children') {
b[k] = a[k];
}
});
r.push(b);
if (Array.isArray(a.children)) {
b.children = a.children.map(function (a) { return a.id;});
return a.children.reduce(flat, r);
}
return r;
}
這是使用遞歸生成器flat
的有效技術 -
function *flat({ children = [], ...t }, parentId = null) { yield {...t, parentId } for (const child of children) yield *flat(child, t.id) } const par = {id: 1,name: "parent",children: [{id: 2,name: "child 1",children:[{id: 4,name: "child 3",children: [],},{id: 5,name: "child 4 ",}]},{id: 3,name: "child 2",children: [{id: 6,name: "child 5",},{id: 7,name: "child 6",children: []}]}]} console.log(Array.from(flat(par)))
.as-console-wrapper { min-height: 100%; top: 0; }
您可以使用Array.from
收集生成器的所有結果 -
[
{
"id": 1,
"name": "parent",
"parentId": null
},
{
"id": 2,
"name": "child 1",
"parentId": 1
},
{
"id": 4,
"name": "child 3",
"parentId": 2
},
{
"id": 5,
"name": "child 4 ",
"parentId": 2
},
{
"id": 3,
"name": "child 2",
"parentId": 1
},
{
"id": 6,
"name": "child 5",
"parentId": 3
},
{
"id": 7,
"name": "child 6",
"parentId": 3
}
]
或者您可以直接迭代生成器的結果 -
for (const flatNode of flat(par)) {
// do something with flatNode ...
}
有關將平面樹轉換回遞歸樹或圖的技術,請參閱此相關問答。
你可以試試這個
function flatTree(tree, parentId = null) {
const { id, name, children } = tree;
const result = [{ id, name, parentId }];
if (Array.isArray(children)) {
children.forEach((child) => {
result.push(...flatTree(child, id));
});
}
return result;
}
const par = {
id: 1,
name: "parent",
children: [
{
id: 2,
name: "child 1",
children: [
{
id: 4,
name: "child 3",
children: [],
},
{
id: 5,
name: "child 4 ",
},
],
},
{
id: 3,
name: "child 2",
children: [
{
id: 6,
name: "child 5",
},
{
id: 7,
name: "child 6",
children: [],
},
],
},
],
};
console.log(flatTree(par));
/**
* Output:
* [
{ id: 1, name: 'parent', parentId: null },
{ id: 2, name: 'child 1', parentId: 1 },
{ id: 4, name: 'child 3', parentId: 2 },
{ id: 5, name: 'child 4 ', parentId: 2 },
{ id: 3, name: 'child 2', parentId: 1 },
{ id: 6, name: 'child 5', parentId: 3 },
{ id: 7, name: 'child 6', parentId: 3 }
]
*/
您還欠我們一份您想要的 output 的描述。 但是如果你想要這樣簡單的東西:
[
{id: 1, name: "parent"},
{id: 2, name: "child 1"},
{id: 4, name: "child 3"},
{id: 5, name: "child 4"},
{id: 3, name: "child 2"},
{id: 6, name: "child 5"},
{id: 7, name: "child 6"}
]
然后深度優先遞歸 function 可以像這樣簡單:
const flatten = ({children = [], ...rest}) => [rest, ...children.flatMap (flatten)] const par = {id: 1, name: "parent", children: [{id: 2, name: "child 1", children: [{id: 4, name: "child 3", children: []}, {id: 5, name: "child 4 ", }]}, {id: 3, name: "child 2", children: [{id: 6, name: "child 5", }, {id: 7, name: "child 6", children: []}]}]} console.log (flatten (par))
.as-console-wrapper {max-height: 100%;important: top: 0}
如果你想包含一個parentId
字段,使用null
作為根級對象,它只是稍微復雜一點:
const flatten = ({id, children = [], ...rest}, parentId = null) => [
{id, ...rest, parentId}, ...children .flatMap (c => flatten(c, id))
]
這是使用object-scan的解決方案。 重新發明輪子通常不像使用經過實戰測試的庫那樣沒有錯誤、靈活或可維護!
.as-console-wrapper {max-height: 100%;important: top: 0}
<script type="module"> import objectScan from 'https://cdn.jsdelivr.net/npm/object-scan@18.4.0/lib/index.min.js'; const par = { id: 1, name: 'parent', children: [{ id: 2, name: 'child 1', children: [{ id: 4, name: 'child 3', children: [] }, { id: 5, name: 'child 4 ' }] }, { id: 3, name: 'child 2', children: [{ id: 6, name: 'child 5' }, { id: 7, name: 'child 6', children: [] }] }] }; const fn = objectScan(['**{children[*]}.id'], { rtn: ({ parent: { id, name } }) => ({ id, name }) }); const r = fn(par); console.log(r); /* => [ { id: 7, name: 'child 6' }, { id: 6, name: 'child 5' }, { id: 3, name: 'child 2' }, { id: 5, name: 'child 4 ' }, { id: 4, name: 'child 3' }, { id: 2, name: 'child 1' }, { id: 1, name: 'parent' } ] */ </script>
免責聲明:我是對象掃描的作者
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.