简体   繁体   English

JavaScript 从数组中删除所有出现的值

[英]JavaScript remove all occurrences of a value from an array

I am using the snippet below to remove all occurrences of a value (ie 97 in this case) from an Array.我正在使用下面的代码片段从数组中删除所有出现的值(即在这种情况下为 97)。 I am unable to understand why the output array has a value 97 in it.我无法理解为什么输出数组中的值为 97。 When I remove 32 it removes all 32s from the array.当我删除 32 时,它会从数组中删除所有 32。 Same with 6. What's wrong with 97 here?与 6 相同。这里的 97 有什么问题? Kind of strange for me.对我来说有点奇怪。 (I was thinking may be 97 is not typed properly or something). (我在想可能是 97 没有正确输入或什么的)。

 var inputArr = [3, 97, 32, 6, 97, 2, 9,32, 1, 32, 97, 97, 6, -1, 5]; function removeItem(array, item) { for(i = 0; i<array.length; i++){ if(array[i] == item) { array.splice(array.indexOf(item), 1); } } } removeItem(inputArr, 97); removeItem(inputArr, 32); removeItem(inputArr, 6); document.getElementById("output").innerHTML = inputArr;
 <p id="output"></p>

Issue is related to the sibling 97s - 1, 32, 97, 97, 6 .问题与兄弟 97s - 1, 32, 97, 97, 6 When you splice the first 97 in this order, the next 97 changes it's index and goes into the first one.当您按此顺序拼接前 97 个时,下一个 97 将更改其索引并进入第一个。 but variable i is tracking after that item.但变量i正在跟踪该项目。

When you remove an item, decrease the index via --i .删除项目时,通过--i减少索引。

Also you can do it via filter function.你也可以通过filter功能来做到这一点。 This will create a new array and you just need to return it.这将创建一个新数组,您只需要返回它。 Here I have created and object with input array and a function which filters the input and returns the current object.在这里,我创建了一个带有input数组的对象和一个过滤input并返回当前对象的函数。 This will let you to cascade the functions which I think is beautiful from the code style and can help you in something.这将使您能够级联我认为代码风格中很漂亮的功能,并且可以在某些方面为您提供帮助。

 const obj = { input: [3, 97, 32, 6, 97, 2, 9,32, 1, 32, 97, 97, 6, -1, 5], removeItem(item) { this.input = this.input.filter(i => i !== item); return this; } } const output = obj.removeItem(97) .removeItem(32) .removeItem(6); console.log(output.input);

While you mutating the array and you increment the index on splicing as well, you could take another approach and start from the end of the array.当您改变数组并在拼接时增加索引时,您可以采用另一种方法并从数组的末尾开始。 That means the following items are still available at their original index and could be checked and spliced if necessary, without leaving some unspliced values.这意味着以下项目仍以其原始索引可用,并且可以在必要时进行检查和拼接,而不会留下一些未拼接的值。

 function removeItem(array, item) { var i = array.length; while (i--) { if (array[i] === item) { array.splice(array.indexOf(item), 1); } } } var inputArr = [3, 97, 32, 6, 97, 2, 9, 32, 1, 32, 97, 97, 6, -1, 5]; removeItem(inputArr, 97); removeItem(inputArr, 32); removeItem(inputArr, 6); console.log(inputArr);

When you delete one element you also have to decrease the value of i .当您删除一个元素时,您还必须减少i的值。

Why this ?为什么这个?

Because splice method changes the contents of an array and the indexes of elements are also changed.因为splice方法改变了数组的内容,元素的索引也改变了。 So, when you need to remove consecutive 97 elements from your array, you have to decrease the value of i .因此,当您需要从数组中remove连续的97元素时,您必须减小i的值。

When you remove the first 97 element from your array, the next 97 element changes it's index, but i is keeping increase.当您从数组中删除前 97 个元素时,下一个 97 个元素会更改它的索引,但i一直在增加。

 var inputArr = [3, 97, 32, 6, 97, 2, 9,32, 1, 32, 97, 97, 6, -1, 5]; function removeItem(array, item) { for(i = 0; i<array.length; i++){ if(array[i] == item) { array.splice(array.indexOf(item), 1); i--; } } } removeItem(inputArr, 97); removeItem(inputArr, 32); removeItem(inputArr, 6); document.getElementById("output").innerHTML = inputArr;
 <p id="output"></p>

For a more easy solution, you can use filter method by passing a callback function as parameter.为了更简单的解决方案,您可以通过将callback函数作为参数传递来使用filter方法。

 var inputArr = [3, 97, 32, 6, 97, 2, 9,32, 1, 32, 97, 97, 6, -1, 5]; function removeItem(array, item) { return array.filter(i => i !== item); } inputArr = removeItem(inputArr, 97); inputArr = removeItem(inputArr, 32); inputArr = removeItem(inputArr, 6); console.log(inputArr);

Use filter使用过滤器

const newArray = inputArr.filter(element => ![97, 32, 6].includes(element));

What filter does is that it created a new array . filter作用是创建一个新array To determine what should be in the new array , it needs to go through each element in the old array, and if the we return true for the current element then it is added to the new array .要确定新array应该包含什么,它需要遍历旧数组中的每个element ,如果我们对当前element返回true ,则将其添加到新array

element => ![97, 32, 6].includes(element) means that we are asking if the array [97, 32, 6] has the value of the current element . element => ![97, 32, 6].includes(element)意味着我们正在询问array [97, 32, 6]是否具有当前element的值。 And since we don't want to add it to the list, then we write !既然我们不想把它添加到列表中,那么我们写! in front of the line, because we want the opposite to happen.在队伍前面,因为我们希望相反的情况发生。

Kinda tricky有点棘手

So when you get a match, you do splice() and hence (i+1)th element comes to i.因此,当您匹配时,您会执行 splice(),因此第 (i+1) 个元素来到 i。 But next iteration start from i+1 so It doesn't match ith element (which was i+1th element).但是下一次迭代从 i+1 开始,所以它不匹配第 i 个元素(即第 i+1 个元素)。

Here last two 97 are continuous hence only 1 is matched.这里最后两个 97 是连续的,因此只有 1 匹配。

Try this -试试这个 -

function removeItem(array, item) {
    for(i = 0; i<array.length; i++){
        if(array[i] == item) {
            array.splice(array.indexOf(item), 1);
            i--;
        }
    }
}

after splice you have to decrease i with 1.拼接后,您必须将 i 减为 1。

array.splice(array.indexOf(item), 1);
i--;

The problem is your modification while a for-loop is being executed, the elements' index is modified as well.问题是您在执行for-loop时进行了修改,元素的索引也被修改了。

A better approach is the use of .filter() function.更好的方法是使用.filter()函数。

Look at this code snippet看看这个代码片段

 var inputArr = [3, 97, 32, 6, 97, 2, 9, 32, 1, 32, 97, 97, 6, -1, 5]; function removeItem(array, item) { return array.filter((i) => i !== item); } inputArr = removeItem(inputArr, 97); inputArr = removeItem(inputArr, 32); inputArr = removeItem(inputArr, 6); document.getElementById("output").innerHTML = inputArr;
 <p id="output"></p>

See?看到了吗? the array was filtered.数组被过滤。

Resource资源

This is an ES5 version and works faster, especially when the array is sparse这是 ES5 版本,运行速度更快,尤其是在数组稀疏时

 function removeAll( array, item ) { for (var i = 0; (i = array.indexOf(item, i)) >= 0; array.splice(i, 1)); } var inputArr = [3, 97, 32, 6, 97, 2, 9, 32, 1, 32, 97, 97, 6, -1, 5]; removeAll(inputArr, 97); removeAll(inputArr, 32); removeAll(inputArr, 6); console.log(inputArr);

you should add i-- like this你应该加我——像这样

var inputArr = [3, 97, 32, 6, 97, 2, 9, 32, 1, 32, 97, 97, 6, -1, 5];

function removeItem(array, item) {
    for (i = 0; i < array.length; i++) {
        if (array[i] == item) {
            array.splice(array.indexOf(item), 1);
            i--;
        }
    }
}
removeItem(inputArr, 97);
removeItem(inputArr, 32);
removeItem(inputArr, 6);

document.getElementById('output').innerHTML = inputArr;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM