提问人:gyan mishra 提问时间:1/30/2023 更新时间:1/30/2023 访问量:89
迭代和搜索 n 维嵌套数组中的元素
Iterating and searching for element in n-dimensional nested array
问:
下面是一个数组
id: 0,
parent: 'p1',
children: [
{
id: 1,
parent: 'p2',
children: [
{
id: 3,
parent: 'p4',
children: []
},
]
},
{
id: 2,
parent: 'p3',
children: [
{
id: 4,
parent: 'p5',
children: []
},
]
}
]
}
我正在尝试根据 id 值搜索一个元素,并将其从数组中删除并 将其替换为空数组
例如,如果我通过
let childTobeReplaced = childrenCollector(4, treeData.children);
结果必须是
{
id: 0,
parent: 'p1',
children: [
{
id: 1,
parent: 'p2',
children: [
{
id: 3,
parent: 'p4',
children: []
},
]
},
{
id: 2,
parent: 'p3',
children: []
}
]
}
childTobeReplaced 必须等于
{
id: 4,
parent: 'p5',
children: []
}
我实施的解决方案如下
function childrenCollector(sourceId, nestedarray) {
for (let index = 0; index < nestedarray.length; index++) {
console.log(nestedarray[index].id)
if (nestedarray[index].id === sourceId) {
let childArray = nestedarray[index];
nestedarray[index] = []
return childArray;
}
if (nestedarray[index].children.length > 0) {
return childrenCollector(sourceId, nestedarray[index].children);
}else{
}
}
}
在这种情况下,我能够遍历 id 1 和 id 3,但无法找到其余的元素 .有人可以给我一些指导吗?
答:
当对象具有子对象时,您的函数将在循环的第一次迭代中,这意味着不会检查数组的其余部分。那不是你想要的。仅当您确定递归调用找到了该元素时,才退出循环。return
其次,不是从中删除索引。它只是将对该索引处对象的引用替换为对空数组的引用。nestedarray[index] = []
nestedarray
下面是一个可能的实现:
function childrenCollector(sourceId, nestedArray) {
const i = nestedArray.findIndex(({id}) => id === sourceId);
let found;
if (i > -1) [found] = nestedArray.splice(i, 1)
else nestedArray.some(({children}) =>
found = childrenCollector(sourceId, children)
);
return found;
}
// Example data from the question
const treeData = {id: 0,parent: 'p1',children: [{id: 1,parent: 'p2',children: [{id: 3,parent: 'p4',children: []},]},{id: 2,parent: 'p3',children: [{id: 4,parent: 'p5',children: []},]}]};
const childTobeReplaced = childrenCollector(4, treeData.children);
console.log(childTobeReplaced);
console.log(treeData);
解释:
使用代码尝试在给定的数组中找到 。回调函数使用解构来让 be 迭代对象的属性。当回调函数返回 true 时,迭代停止,并将相应的索引分配给 。如果没有匹配项,将设置为 -1。findIndex
id
id
findIndex
i
i
如果存在匹配项,将从该索引处的数组中提取该元素,并将返回已删除元素的数组。由于只有一个删除的元素,因此该数组将只有一个元素。这个元素被赋值给 ,同样使用解构赋值。splice
found
如果没有匹配项,则再次迭代数组,但现在进行递归调用。对于此迭代,它也将在成功后立即停止迭代。在每次迭代中,设置为递归调用的结果。一旦这是一个对象(表示找到了某些东西),循环就会退出。some
found
无论哪种情况,都将返回对象(如果有),否则 .found
undefined
评论
下面是一个简单的不可变解决方案:
let remove = (node, id) => ({
...node,
children: node.children
.filter(child => child.id !== id)
.map(child => remove(child, id))
})
给定一个节点,它会删除具有给定 ID 的子节点,然后对每个剩余的子节点应用相同的过程。
评论
下一个:React Js 数组操作
评论