[英]Recursively make a nested object given an array of objects and array of children?
[英]Recursively search for a nested object in array and update its children
我正在尝试通过对象的唯一 id递归搜索对象的数组,然后将对象推入其部分数组,然后返回整个数组
例如,这是我要搜索的数组:
car = [
{
id: 13,
title: 'Component13',
parts: [
{
id: 784,
title: 'Component242',
parts: [
]
},
{
id: 9,
type: 'mitigation',
parts: [
{
id: 68,
type: 'mitigation22',
parts: [
]
},
{
id: 88,
type: 'threat',
parts: [
]
}
]
}
]
},
{
id: 3,
title: 'Component13',
parts: [
{
id: 60,
title: 'Component34',
parts: [
]
},
{
id: 51,
type: 'threat',
parts: [
{
id: 38,
type: 'mitigation22',
parts: [
]
}
]
}
]
}
]
如果我想将此对象插入到 id 38 中的部分子数组中:
{
id: 34,
title: 'Component211',
parts: [
]
}
......结果应该是这样的:
...commented out the first block to save space
{
id: 3,
title: 'Component13',
parts: [
{
id: 60,
title: 'Component34',
parts: [
]
},
{
id: 51,
type: 'threat',
parts:[
{
id: 38,
type: 'mitigation22',
parts: [
{
id: 34,
title: 'Component211',
parts: [
]
}
]
}
]
}
]
}
考虑到我可能需要在汽车阵列的任何级别插入一个对象,最好的方法是什么?
我无力的尝试:
const updatePart = (id, obj, car) => {
for (var i = 0; i < car.length; i++) {
if (car[i].id == id) {
car[i].parts.push(obj)
} else {
car[i].parts.map(function (item) {
updatePart(id, obj, item)
})
}
return car
}
}
car = updateTree(id, obj, car);
如果您想获得一个新数组,您可以使用新的parts
属性映射对象。
const update = (array, id, object) => array.map(o => o.id === id ? { ...o, parts: [...o.parts, object] } : { ...o, parts: update(o.parts, id, object) } ); var car = [{ id: 13, title: 'Component13', parts: [{ id: 784, title: 'Component242', parts: [] }, { id: 9, type: 'mitigation', parts: [{ id: 68, type: 'mitigation22', parts: [] }, { id: 88, type: 'threat', parts: [] }] }] }, { id: 3, title: 'Component13', parts: [{ id: 60, title: 'Component34', parts: [] }, { id: 51, type: 'threat', parts: [{ id: 38, type: 'mitigation22', parts: [] }] }] }], result = update(car, 38, { id: 34, title: 'Component211', parts: [] }); console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
如果找到id
则采用短路的变异方法。
const update = (array, id, object) => array.some(o => o.id === id ? o.parts.push(object) : update(o.parts, id, object) ); var car = [{ id: 13, title: 'Component13', parts: [{ id: 784, title: 'Component242', parts: [] }, { id: 9, type: 'mitigation', parts: [{ id: 68, type: 'mitigation22', parts: [] }, { id: 88, type: 'threat', parts: [] }] }] }, { id: 3, title: 'Component13', parts: [{ id: 60, title: 'Component34', parts: [] }, { id: 51, type: 'threat', parts: [{ id: 38, type: 'mitigation22', parts: [] }] }] }]; update(car, 38, { id: 34, title: 'Component211', parts: [] }); console.log(car);
.as-console-wrapper { max-height: 100% !important; top: 0; }
也许考虑一个查找对象来存储对树中节点的引用的平面列表:
let memo = {};
const buildMemo = (arr) => {
arr.forEach(item => {
memo[item.id] = item;
if (item.parts) buildMemo(item.parts);
}
};
buildMemo(car);
现在,如果您需要对 id = 34 的car
树节点进行一些操作,您可以从 memo[34] 中获取引用。 如果您从car
阵列中添加/删除/移动节点,您将需要逻辑来更新备忘录
您的updatePart
需要一个数组,但在您的map
您使用的是递归发送对象。 所以你根本不需要使用map
(或forEach
,这里最适合):
var car=[{id:13,title:"Component13",parts:[{id:784,title:"Component242",parts:[]},{id:9,type:"mitigation",parts:[{id:68,type:"mitigation22",parts:[]},{id:88,type:"threat",parts:[]}]}]},{id:3,title:"Component13",parts:[{id:60,title:"Component34",parts:[]},{id:51,type:"threat",parts:[{id:38,type:"mitigation22",parts:[]}]}]}]; const updatePart = (id, obj, car) => { for (var i = 0; i < car.length; i++) { console.log(car[i]) if (car[i].id == id) { car[i].parts.push(obj) } else { updatePart(id, obj, car[i].parts) } } return car } const obj = { id: 34, title: 'Component211', parts: [ ] } car = updatePart(38, obj, car); console.log(car)
您的代码中的其他错误是return car
inside loop,您应该在循环完成后返回并且您声明updatePart
不是updateTree
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.