在forEach循环上的拼接不能正常工作

时间:2016-04-02 18:30:21

标签: javascript

我有以下背景:

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数组中位置2obj的项目。但由于某种原因,它无法正常工作。

我做错了什么?

3 个答案:

答案 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)

来自Array#forEach

  

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]);