给出一系列像这样的对象:
var items = [{
id: 1
}, {
id: 2,
child: {
id: 3
}
}, {
id: 4,
child: {
id: 5,
child: {
id: 6
}
}
}];
我需要一种方法来删除任何级别的项目。这段代码做了我想要的,但有更好的方法吗?
最初我尝试使用一个递归函数,但无法使其工作。
var removed = removeItems(items, 5);
print(removed);
function removeItems(items, id) {
items.forEach(function(item, index, allItems) {
if (item.id === id) {
items.splice(index, 1);
}
if (item.child) {
item = testChild(item, item.child, id);
}
});
return items;
}
function testChild(parent, child, id) {
if (child.id === id) {
delete parent.child
return parent;
} else {
if (child.child) {
return testChild(child, child.child, id);
}
return parent;
}
}
function print(obj) {
document.querySelector('#out').innerHTML += JSON.stringify(obj, null, 2);
}
jsfiddle:https://jsfiddle.net/syvf46uL/12/
答案 0 :(得分:1)
这是一个通用的删除功能,可以按你的意愿工作。
var items = [{
id: 1
}, {
id: 2,
child: { id: 3 }
}, {
id: 4,
child: {
id: 5,
child: {
id: 6
}
}
}
];
function remove(src, predicate) {
// for Array
if (Array.isArray(src)) {
for (var i=src.length-1; i>-1; i--) {
if (predicate(src[i])) {
src.splice(i, 1);
} else {
remove(src[i], predicate);
}
}
}
// for Object
else {
for (var i in src) {
if (predicate(src[i])) {
delete src[i];
} else {
remove(src[i], predicate);
}
}
}
}
// remove id == 1
remove(items, function(element) {
return element.id && element.id == 1;
});
console.log(JSON.stringify(items));
// remove id == 6
remove(items, function(element) {
return element.id && element.id == 6;
});
console.log(JSON.stringify(items));
您的代码的一个重要问题,一个常见的错误,就是您尝试通过splice
方法缩小数组 - 同时向前迭代。这将导致您每次删除元素时跳过元素。
以这种方式思考,你正在迭代0->length
;你删除ith
元素;现在您之前的(i + 1)th
元素已成为您的ith
元素;但是您仍在迭代0->length
,因此会跳过新的ith
元素并转到(i + 1)th
元素,这是您以前的(i + 2)th
元素。这可以通过向后迭代length->0
来解决;数组的收缩不会影响迭代器,因为收缩总是从病房i+1->length
开始,但是你从i->0
迭代。