splice无法从数组中删除元素

4

我在使用splice从数组中删除元素,但是它并没有起作用。 据我所知,代码看起来没问题,但可能我漏看了什么。 请看一下。这里的“state”是包含对象的数组。

 let removeFromState = state;
            for(var i=0;i<removeFromState.length;i++){
                if(removeFromState[i].index===action.index){
                    removeFromState.splice[i,1];
                }
            }
            return removeFromState;

我简直不敢相信,我竟然这么傻。我一直在看它,但并没有看到它就在我的眼前。但我很高兴我把它发在这里,因为有人指出我错过了一些条目,那是因为尽管我删除了一些条目,但我还在增加“i”的值。


使用()代替[] - Eddie
1
这个回答解决了你的问题吗?循环遍历数组并删除元素,而不中断for循环 - gre_gor
6个回答

14

有两个问题:

  1. 一个打字错误,你正在使用方括号[i,1],而应该使用括号(i,1)。方括号是属性访问器。(之所以不是语法错误是因为JavaScript有一个逗号运算符,[i,1]计算为[1]。它不是运行时错误的原因是functionname[1]在函数上查找属性“1”,然后忽略它找到的任何值。)

  2. 循环将跳过删除条目后的条目,因为您删除了条目并增加了i。所以当您删除第5个条目时,第6个条目变成了#5 - 然后您移动到i == 6。所以你从来没有看过新的#5条目。

要解决#2问题,要么只有在不删除条目时才增加i,要么反向循环。

所以可以:

var i = 0;
while (i < removeFromState.length) {
    if(removeFromState[i].index === action.index) {
        removeFromState.splice(i, 1);
    } else {
        ++i;
    }
}
或者
for (var i = removeFromState.length - 1; i >= 0; --i) {
    if(removeFromState[i].index === action.index) {
        removeFromState.splice(i, 1);
    }
}

或者,创建一个新的数组,仅包含您想要保留的条目:

或者,创建一个新的数组,仅包含您想要保留的条目:

var newArray = removeFromState.filter(function(entry) { return entry.index !== action.index; });

谢谢你的回答,特别是第二点,我没有想到。是的,我可能会错过一些条目。所以,使用i--而不是i++应该可以解决这个问题,对吧? - faraz
@faraz:我已经在答案的末尾添加了一些示例。 - T.J. Crowder
2
非常感谢,非常有帮助。 - faraz

2

splice是一种方法,您需要用括号调用它,而不是方括号。方括号用于索引(JavaScript非常灵活,并在您“索引”该方法时默默返回undefined)。请尝试使用以下代码:

removeFromState.splice(i, 1);

2
我被这个问题卡了几个小时。我确实发现,当你拼接一个数组时,它会返回从原始数组中拼接的元素。
let  originalArray = ["Apples","Oranges","Kiwi"];
let newArray = originalArray.splice(0,1);
console.log(newArray);

我原本期望在spliced变量中得到修改后的originalArray,但实际上返回的是被删除的元素。

解决方法是

console.log(originalArray);

无论splice返回什么,我们可能不需要它,我们需要检查原始数组,因为它是被切片的那个。 原始数组包含了我期望的答案,即["Oranges","Kiwi"]。


这与问题有什么关系呢?OP没有在任何地方保存splice的结果。而且,这种行为已经被清楚地记录了。 - gre_gor

1
错误在于:你使用了方括号而不是圆括号。

function remove(state, action) {
  let removeFromState = state;

  for (var i = 0; i < removeFromState.length; i++) {
    if (removeFromState[i].index === action.index) {
      removeFromState.splice(i, 1);
      i--;    // After deleting, counter reduced
    }
  }
  return removeFromState;
}

console.log(remove([{index: 3}, {index: 3}, {index: 3}], {index: 3}));


不需要while循环,也不需要复杂的for循环,只需在删除时减少计数器即可! - Abhijit Kar ツ

0
问题在于你如何调用 splice,它是一个函数,需要像 splice(i, 1) 这样调用。
你可以将函数简化为以下形式。
let removeFromState = state;
const findEntry = entry => entry.index === action.index;
removeFromState.splice(removeFromState.findIndex(findEntry), 1);
return removeFromState;

-1

removeFromState 被实例化为 let 常量,因此不可变。如果将 let removeFromState 更改为 var removeFromState,它应该可以工作 (.


let 并不意味着它是一个常量。 - gre_gor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接