提问人:Petervw 提问时间:9/15/2023 更新时间:9/15/2023 访问量:32
使用reduce扁平化数组后更改特定对象值,如何操作?
Change specific object value after array is flattened with reduce, how to?
问:
我有一个嵌套的对象数组,可以深入多个级别。出于其他目的,我不得不将对象数组展平为 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;
}, []);
}
假设我想将测试更新为 true,仅在 id 10 中。在原始阵列上执行此操作的最简单方法是什么?当我更新扁平化数组对象时,引用不再链接到原始数组。
答:
2赞
Alexander Nenashev
9/15/2023
#1
由于对象具有硬结构,因此可以递归迭代其项并找到目标对象:
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,
// filter id === 3 and all descendants
(item, parents) => item.id === 3 || parents.some(parent => parent.id === 3),
// update test to true
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>
评论