我有以下背景:
https://jsfiddle.net/eqntaqbt/2/
obj.forEach(function(user, index){
var userName = user.name;
console.log(index, userName);
if(index === 5 || index === 2){
obj.splice(index, 1);
}
});
我正在使用forEach
循环和splice
来移除5
数组中位置2
和obj
的项目。但由于某种原因,它无法正常工作。
我做错了什么?
答案 0 :(得分:6)
您的代码在循环时拼接。即使它们不再存在,也可以访问拼接元素。这会导致未定义的元素。
您可以考虑Array#filter
var obj = [{ "index": 0, "name": "Odonnell Noble", "gender": "male", "company": "DIGIQUE", "eail": "odonnellnoble@digique.com" }, { "index": 1, "name": "Marie Oneal", "gender": "female", "company": "CANOPOLY", "email": "marieoneal@canopoly.com" }, { "index": 2, "name": "Adrienne Marsh", "gender": "female", "company": "XOGGLE", "email": "adriennemarsh@xoggle.com" }, { "index": 3, "name": "Goff Mullins", "gender": "male", "company": "ENDIPIN", "email": "goffmullins@endipin.com" }, { "index": 4, "name": "Lucile Finley", "gender": "female", "company": "AQUASSEUR", "email": "lucilefinley@aquasseur.com" }, { "index": 5, "name": "Pitts Mcpherson", "gender": "male", "company": "QUARX", "email": "pittsmcpherson@quarx.com" }];
obj = obj.filter(function (user, index) {
return (user.index !== 5 && user.index !== 2);
});
document.write('<pre>' + JSON.stringify(obj, 0, 4) + '</pre>');
答案 1 :(得分:1)
forEach()处理的元素范围在第一个之前设置 调用回调。之后附加到数组的元素 回调不会访问对forEach()开始的调用。如果 更改数组的现有元素的值,传递值 回调将是forEach()访问它们时的值; 访问前删除的元素不会被访问。
obj.forEach(function(user, index){
var userName = user.name;
//console.log(index, userName);
if(user.index === 5 || user.index === 2){
this.splice(index, 1);
}
}.bind(obj));
这是工作fiddle
答案 2 :(得分:0)
forEach意味着所谓的副作用。
您的代码存在的问题是,您在迭代数组时正在更改数组。因此,如果删除一个项目,则会立即重新分配该数组的所有其他索引。这就是为什么在删除一个项目后,进一步删除不能做到所需的事情(在所需的位置)。
因此forEach适用于影响实际数组之外的事物,即迭代。
这对于一个名为filter的函数来说是一个完美的用例,因为实际上,你正在对你的列表做什么:你想过滤掉一些项目。
array = array.filter(function(item, index) {
return (index !== 5 && index !== 2)
}
Filter将函数作为参数排除,它本身将为数组中的每个项调用。如果函数对一个项返回true,则保留 - 否则删除。这就是为什么逻辑表达式必须在这里稍微改变一下:它的内容如下:保留不属于索引5且不属于索引2的项。这类真或假的返回函数称为谓词。
如果您想过滤掉更多指数怎么办?使用locical运算符的表达式很快就会变长。
您可以在索引列表中使用数组方法indexOf,每次将数组的当前索引传递给它。这将返回一个位置,如果不在,则返回-1。在后一种情况下,您希望将项目保留在数组中。
array = array.filter(function(item, current_index) {
return ([2, 5].indexOf(current_index) === -1)
}
另外,你可以将它包装在一个函数中:
function removeIndices(array, indices) {
return array.filter(function(item, current_index) {
return (indices.indexOf(current_index) === -1)
})
}
最后:
array = removeIndices(array, [2, 5]);