如何从对象的嵌套数组中递归删除特定对象? [英] how to delete specific object from nested array of objects recursively?
问题描述
数据:
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 ,从此数据中删除,我尝试过:
I need to remove "id": 5 form this data, I tried this :
data.filter(function f(o) {
return o.id !== 5 ||
o.child && (o.child.filter(f)).length
})
最终输出将没有id:5,在某些情况下,第一个列表id:1也可以删除.递归简化此操作很热门它可能没有N个子级列表,必须遍历每个列表并将其删除?
Final output would be without id:5, In some cases the first list id:1 also can be erasable. Hot to simplify this recursively It may have N no of children list, have to loop through every list and delete it?
推荐答案
没有简单(非hacky)方法来删除元素而不循环遍历数组.
There is no easy (non-hacky) way to remove the element without looping through the arrays.
您需要先过滤数据数组,然后映射其余条目并递归过滤其child
属性,例如:
You need to first filter the data array, then map over the remaining entries and filter their child
property recursively, e.g.:
function removeIdDeep(data, idToRemove) {
const filtered = data.filter(entry => entry.id !== idToRemove);
return filtered.map(entry => {
if(!entry.child) return entry;
return {...entry, child: removeIdDeep(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 I", "type":"list", "id":7 } ];
function removeIdDeep(data, idToRemove) {
const filtered = data.filter(entry => entry.id !== idToRemove);
return filtered.map(entry => {
if(!entry.child) return entry;
return {...entry, child: removeIdDeep(entry.child, idToRemove)};
});
}
console.log(removeIdDeep(data, 5));
如果要在删除元素之前提示用户,只需将confirm
提示添加到过滤器中即可:
If you want to prompt the user before removing elements, you can just add the confirm
prompt to the filter:
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 } ];
function removeIdDeep(data, idToRemove) {
const filtered = data.filter(entry => {
if(entry.id === idToRemove) {
const numChilds = entry.childs ? entry.childs.length : 0;
return !confirm(`Are you sure you want to delete ${entry.name}? It contains ${numChilds} children.`);
}
return true;
});
return filtered.map(entry => {
if(!entry.child) return entry;
return {...entry, child: removeIdDeep(entry.child, idToRemove)};
});
}
console.log(removeIdDeep(data, 5));
如果要显示一些自定义警告,则必须首先找到该元素,显示警告,然后才调用removeIdDeep
.
If you want to display some custom warning, you'll have to first find the element, display the warning and only then call removeIdDeep
.
这篇关于如何从对象的嵌套数组中递归删除特定对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!