我有一个嵌套的对象数组,它可以深入多个级别。出于其他目的,我必须将对象数组展平为 1 级(非嵌套)数组。 当我只知道 id 时,如何更新 1 个特定对象?
这是对象数组的示例:
let items = [
{
id: 2,
test: false,
items: []
},
{
id: 3,
test: false,
items: [
{
id: 4,
test: false,
items: [
{
id: 10,
test: false,
items: []
},
]
},
]
},
{
id: 1,
test: false,
items: []
},
];
我在这个线程中使用了这种展平方法:递归地深度展平 JavaScript 对象
function flatten(xs) {
return xs.reduce((acc, x) => {
acc = acc.concat(x);
if (x.items) {
acc = acc.concat(flatten(x.items));
x.items = [];
}
return acc;
}, []);
}
假设我想将 test 更新为 true,仅在 id 10 中。在原始数组上执行此操作的最简单方法是什么?当我更新展平数组对象时,引用不再链接到原始数组。
由于您的对象具有硬结构,您可以递归地迭代它们的项目并找到您的目标对象:
const findObject = (items, id) => {
for(const item of items){
if(item.id === id){
return item;
}
if(item.items.length){
const found = findObject(item.items, id);
if(found) return found;
}
}
return null;
};
const found = findObject(items, 10)
found.test = true;
console.log(items);
<script>
let items = [
{
id: 2,
test: false,
items: []
},
{
id: 3,
test: false,
items: [
{
id: 4,
test: false,
items: [
{
id: 10,
test: false,
items: []
},
]
},
]
},
{
id: 1,
test: false,
items: []
},
];
</script>
更高级的代码将具有遍历树并更新项目的功能。例如,在这里我们更新 id 为 3 的 item 的所有后代,并将它们的
test
设置为 true
:
const transformTree = (items, filterCb, updateCb, parents = []) => {
for(const item of items){
if(filterCb(item, parents)){
if(false === updateCb(item, parents)){
return false;
}
}
if(item.items.length){
if(false === transformTree(item.items, filterCb, updateCb, parents.concat(item))){
return false;
}
}
}
};
transformTree(items, (item, parents) => parents.some(parent => parent.id === 3), item => item.test = true);
console.log(items);
<script>
let items = [
{
id: 2,
test: false,
items: []
},
{
id: 3,
test: false,
items: [
{
id: 4,
test: false,
items: [
{
id: 10,
test: false,
items: []
},
]
},
]
},
{
id: 1,
test: false,
items: []
},
];
</script>