我有如下的对象数组。这里的子元素可以深度嵌套,它也可以包含其他的子元素。
let response = [{
id: 4321,
name: 'Education',
parentId: null,
children: [{
id: 1234,
name: 'category1',
parentId: 4321,
children: [{
id: 8327548,
name: '001',
parentId: 1234,
}, {
id: 8327549,
name: '002',
parentId: 1234,
}],
}, {
id: 6786,
name: 'Associations',
parentId: 4321,
}, {
id: 8262439,
name: 'category1',
parentId: 4321,
}, {
id: 8245,
name: 'Rights',
parentId: 4321,
children: [{
id: 2447,
name: 'Organizations',
parentId: 8245,
}, {
id: 9525,
name: 'Services',
parentId: 8245,
}, {
id: 8448,
name: 'Organizations',
parentId: 8245,
}],
}, {
id: 8262446,
name: 'Women's Rights',
parentId: 4321,
}],
}, {
id: 21610,
name: 'Agriculture',
parentId: null,
children: [{
id: 3302,
name: 'categoryABC',
parentId: 21610,
children: [{
id: 85379,
name: 'categoryABC - General',
parentId: 3302,
}, {
id: 85380,
name: 'categoryABC Technology',
parentId: 3302,
}],
}, {
id: 8303,
name: 'Fungicides',
parentId: 21610,
children: [{
id: 8503,
name: 'Fungicides - General',
parentId: 8303,
}],
}],
}];
我想让它成为一个平面数组的对象,但我想添加父名称(其中parentId为null)到每个对象在各自的父。
预期输出:
[
{
id: 8327548,
name: "001",
parentId: 1234
mainParent: "Education"
}, {
id: 8327549,
name: "002",
parentId: 1234,
mainParent: "Agriculture"
},
// ...OTHER OBJECTS....
]
到目前为止我做了什么
function flat(array) {
var result = [];
array.forEach(function (a) {
result.push(a);
if (Array.isArray(a.children)) {
result = result.concat(flat(a.children));
delete a.children;
}
});
return result;
}
它给出了对象的平面数组但我不能给每个对象添加parent name属性
有人能帮帮我吗?
您可以采用递归方法,将第一个找到的name
切换为mainParent
。
const
flat = mainParent => o => o.children
? o.children.flatMap(flat(mainParent || o.name))
: { ...o, mainParent },
response = [{ id: 4321, name: "Education", parentId: null, children: [{ id: 1234, name: "category1", parentId: 4321, children: [{ id: 8327548, name: "001", parentId: 1234 }, { id: 8327549, name: "002", parentId: 1234 }] }, { id: 6786, name: "Associations", parentId: 4321 }, { id: 8262439, name: "category1", parentId: 4321 }, { id: 8245, name: "Rights", parentId: 4321, children: [{ id: 2447, name: "Organizations", parentId: 8245 }, { id: 9525, name: "Services", parentId: 8245 }, { id: 8448, name: "Organizations", parentId: 8245 }] }, { id: 8262446, name: "Women's Rights", parentId: 4321 }] }, { id: 21610, name: "Agriculture", parentId: null, children: [{ id: 3302, name: "categoryABC", parentId: 21610, children: [{ id: 85379, name: "categoryABC - General", parentId: 3302 }, { id: 85380, name: "categoryABC Technology", parentId: 3302 }] }, { id: 8303, name: "Fungicides", parentId: 21610, children: [{ id: 8503, name: "Fungicides - General", parentId: 8303 }] }] }],
result = response.flatMap(flat());
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
这是一个相当干净的递归,当节点中没有children
时停止。我们捕获沿层次结构找到的第一个name
值,并将其传递下去。
const flat = (xs, name = null) =>
xs .flatMap (x => x .children
? flat (x .children, name || x .name)
: [{...x, mainParent: name}]
)
const response = [{id: 4321, name: "Education", parentId: null, children: [{id: 1234, name: "category1", parentId: 4321, children: [{id: 8327548, name: "001", parentId: 1234}, {id: 8327549, name: "002", parentId: 1234}]}, {id: 6786, name: "Associations", parentId: 4321}, {id: 8262439, name: "category1", parentId: 4321}, {id: 8245, name: "Rights", parentId: 4321, children: [{id: 2447, name: "Organizations", parentId: 8245}, {id: 9525, name: "Services", parentId: 8245}, {id: 8448, name: "Organizations", parentId: 8245}]}, {id: 8262446, name: "Women's Rights", parentId: 4321}]}, {id: 21610, name: "Agriculture", parentId: null, children: [{id: 3302, name: "categoryABC", parentId: 21610, children: [{id: 85379, name: "categoryABC - General", parentId: 3302}, {id: 85380, name: "categoryABC Technology", parentId: 3302}]}, {id: 8303, name: "Fungicides", parentId: 21610, children: [{id: 8503, name: "Fungicides - General", parentId: 8303}]}]}]
console .log (flat (response))
.as-console-wrapper {max-height: 100% !important; top: 0}
不那么晦涩,但仍然相当简洁。
const response = [{ id: 4321, name: 'Education', parentId: null, children: [{ id: 1234, name: 'category1', parentId: 4321, children: [{ id: 8327548, name: '001', parentId: 1234 }, { id: 8327549, name: '002', parentId: 1234 }] }, { id: 6786, name: 'Associations', parentId: 4321 }, { id: 8262439, name: 'category1', parentId: 4321 }, { id: 8245, name: 'Rights', parentId: 4321, children: [{ id: 2447, name: 'Organizations', parentId: 8245 }, { id: 9525, name: 'Services', parentId: 8245 }, { id: 8448, name: 'Organizations', parentId: 8245 }] }, { id: 8262446, name: 'Women's Rights', parentId: 4321 }] }, { id: 21610, name: 'Agriculture', parentId: null, children: [{ id: 3302, name: 'categoryABC', parentId: 21610, children: [{ id: 85379, name: 'categoryABC - General', parentId: 3302 }, { id: 85380, name: 'categoryABC Technology', parentId: 3302 }] }, { id: 8303, name: 'Fungicides', parentId: 21610, children: [{ id: 8503, name: 'Fungicides - General', parentId: 8303 }] }] }];
function flatten(arr, mainParent = null) {
if (!arr) return;
let result = [];
for (const obj of arr) {
result.push(...(flatten(obj.children, mainParent ?? obj.name) ?? [{ ...obj, mainParent }]));
}
return result;
}
console.log(flatten(response));
.as-console-wrapper { max-height: 100% !important; top: 0; }
一个可能的解决方案可以完全基于一个单一的,虽然递归实现的reduce
任务,其中累积和递归传递的对象同时携带信息,mainParent
值和递归收集的最终result
…
function recursivelyReassambleAndCollectChildlessItems(
{ mainParent, result }, { children, ...item }
) {
result = result.concat(children && children.reduce(
recursivelyReassambleAndCollectChildlessItems, {
// was:
// mainParent: mainParent ?? item.name,
/**
* OP quote:
* "... but I want to add parent name
* (which parentId is null) to every
* objects inside that respective parent."
*/
mainParent: item.parentId === null ? item.name : mainParent,
result: [],
}
).result || { mainParent, ...item });
return { mainParent, result };
}
const response = [{
id: 4321,
name: 'Education',
parentId: null,
children: [{
id: 1234,
name: 'category1',
parentId: 4321,
children: [{
id: 8327548,
name: '001',
parentId: 1234,
}, {
id: 8327549,
name: '002',
parentId: 1234,
}],
}, {
id: 6786,
name: 'Associations',
parentId: 4321,
}, {
id: 8262439,
name: 'category1',
parentId: 4321,
}, {
id: 8245,
name: 'Rights',
parentId: 4321,
children: [{
id: 2447,
name: 'Organizations',
parentId: 8245,
}, {
id: 9525,
name: 'Services',
parentId: 8245,
}, {
id: 8448,
name: 'Organizations',
parentId: 8245,
}],
}, {
id: 8262446,
name: 'Women's Rights',
parentId: 4321,
}],
}, {
id: 21610,
name: 'Agriculture',
parentId: null,
children: [{
id: 3302,
name: 'categoryABC',
parentId: 21610,
children: [{
id: 85379,
name: 'categoryABC - General',
parentId: 3302,
}, {
id: 85380,
name: 'categoryABC Technology',
parentId: 3302,
}],
}, {
id: 8303,
name: 'Fungicides',
parentId: 21610,
children: [{
id: 8503,
name: 'Fungicides - General',
parentId: 8303,
}],
}],
}];
console.log(response
.reduce(recursivelyReassambleAndCollectChildlessItems, { result: [] })
.result
)
.as-console-wrapper { min-height: 100%!important; top: 0; }