Javascript 如何从嵌套对象数组中递归删除特定对象?
数据: 我需要从该数据中删除“id”:5,我尝试了以下方法:Javascript 如何从嵌套对象数组中递归删除特定对象?,javascript,ecmascript-6,Javascript,Ecmascript 6,数据: 我需要从该数据中删除“id”:5,我尝试了以下方法: var data = [ { "name":"list1", "type":"list", "id":1, "child":[ { "name":"list2", "type":"subList", "id":2, "child":[
var data = [
{
"name":"list1",
"type":"list",
"id":1,
"child":[
{
"name":"list2",
"type":"subList",
"id":2,
"child":[
{
"name":"list3",
"type":"subList",
"id":3
},
{
"name":"list4",
"type":"list",
"id":4,
"child":[
{
"name":"list5",
"type":"list",
"id":5
}
]
}
]
},
{
"name":"list6",
"type":"subList",
"id":6
}
]
},
{
"name":"list I",
"type":"list",
"id":7
}
]
最终输出将没有id:5,在某些情况下,第一个列表id:1也可以擦除。要递归地简化这个过程,它可能没有N个子列表,必须循环遍历每个列表并删除它?如果不循环遍历数组,没有简单(非黑客)的方法来删除元素
您需要首先筛选数据数组,然后映射其余条目,并递归筛选其子属性,例如:
函数removedeep(数据,idToRemove){
const filtered=data.filter(entry=>entry.id!==idToRemove);
返回筛选的.map(条目=>{
如果(!entry.child)返回条目;
返回{…entry,child:removeddeep(entry.child,idToRemove)};
});
}
var data=[{“name”:“list1”,“type”:“list”,“id”:1,“child”:[{“name”:“list2”,“type”:“subList”,“id”:2,“child”:[{“name”:“list3”,“type”:“subList”,“id”:3},{“name”:“list4”,“type”:“list”,“id”:4,“child”:[{“name”:“list5”,“type”:“list”,“id”:5}]}}}},{“name”:“list6”,“type”:“subList”,“id”:6},{“name”:“list”,“type”:“list I”,“type”:“list”:“列表”,“id”:7}];
函数removeIdDeep(数据,idToRemove){
const filtered=data.filter(entry=>entry.id!==idToRemove);
返回筛选的.map(条目=>{
如果(!entry.child)返回条目;
返回{…entry,child:removeddeep(entry.child,idToRemove)};
});
}
console.log(removeddeep(data,5));
您可以创建一个递归函数,为每个子数组应用过滤器,如下所示:
data.filter(function f(o) {
return o.id !== 5 ||
o.child && (o.child.filter(f)).length
})
var数据=[
{
“名称”:“列表1”,
“类型”:“列表”,
“id”:1,
“儿童”:[
{
“名称”:“列表2”,
“类型”:“子列表”,
“id”:2,
“儿童”:[
{
“名称”:“列表3”,
“类型”:“子列表”,
“id”:3
},
{
“名称”:“列表4”,
“类型”:“列表”,
“id”:4,
“儿童”:[
{
“名称”:“列表5”,
“类型”:“列表”,
“id”:5
}
]
}
]
},
{
“名称”:“列表6”,
“类型”:“子列表”,
“id”:6
}
]
},
{
“姓名”:“名单一”,
“类型”:“列表”,
“id”:7
}
]
常量过滤器数据=(el)=>{
如果(el.id==5){
返回错误
}
如果(儿童){
el.child=el.child.filter(filterData)
}
返回真值
}
const filtered=data.filter(filterData)
console.log(过滤)
不直接更改子项,更好地传播
const filterData = (el) => {
if(el.id === 5) {
return false
}
if(el.child) {
el.child = el.child.filter(filterData)
}
return true
}
const filtered = data.filter(filterData)
因此,如果一个孩子有你想要删除的ID,应该删除家长?或者只是孩子?如果家长包含删除的项目,我需要显示警报以确认用户同时删除家长和孩子Bad解决方案,它将更改原始中的孩子道具objects@DmitryReutov您还可以使用扩展运算符(如您在回答中所建议的)获取像这样的[…data].filter(filterData)的数据的临时数组
这并不是毫无意义的,它被称为数组克隆,你可以这样做,以避免改变原始数组,如果OP当然关心它,而他似乎并不关心。因此,既然OP只想删除这些特定元素,那么不管原始数组是否被改变,因此即使不进行克隆,我的解决方案也是如此不坏。克隆对象和数组的问题没有问题。我不理解为什么我们需要这个返回{…entry,child:removeddeep(entry.child,idToRemove)};相反,只需返回removeddeep(entry.child,idToRemove)@Learntocode它将复制条目并用removeddeep(entry.child,idToRemove)替换子属性
-如果只返回最后一部分,则结果将是嵌套数组,叶节点除外(用于处理它)谢谢。如果一个父项应该被删除,但它包含子项,那么我应该指出一个用户说like child也将被删除。@Learntocode我添加了一个小例子,如何添加一个确认提示,让用户确认删除。你能解释一下{…elem,child:deleteObject(elem.child,id)}这条线please@Learntocode我们分散元素以不更改原始元素,因此您将获得原始数组的副本,而不删除元素,但原始数组将保持原样
deleteObject = (arr, id) => {
return arr
.filter(elem => elem.id !== id)
.map(elem => elem.child
? {
...elem,
child: deleteObject(elem.child, id)
} : elem)
}