如何在 JavaScript 中迭代数组并删除元素 [重复]
Posted
技术标签:
【中文标题】如何在 JavaScript 中迭代数组并删除元素 [重复]【英文标题】:How to iterate over an array and remove elements in JavaScript [duplicate] 【发布时间】:2013-04-27 11:33:12 【问题描述】:我有一个元素数组,需要从中删除某些元素。问题是 javascript 似乎没有 for each 循环,如果我使用 for 循环,我会遇到问题,它基本上试图检查数组边界之外的元素,或者由于索引更改而丢失数组中的元素.让我告诉你我的意思:
var elements = [1, 5, 5, 3, 5, 2, 4];
for(var i = 0; i < elements.length; i++)
if(elements[i] == 5)
elements.splice(i, 1);
问题是当元素[1]被移除时,元素[2]变成了元素[1]。所以第一个问题是某些元素从未被检查过。另一个问题是 .length 发生了变化,如果我对边界进行硬编码,那么我可能会尝试检查超出数组边界的元素。那么,完成这个极其简单的事情的最佳方法是什么?
【问题讨论】:
elements.splice(i--, 1);
我不喜欢 "--" 或 "++" 语法,但是从数组 +1 的开头开始时很有用的提示
另见:Looping through array and removing items, without breaking for loop
【参考方案1】:
var elements = [1, 5, 5, 3, 5, 2, 4];
var i = elements.length;
while (i--)
if (elements[i] == 5)
elements.splice(i, 1);
console.log(elements);
【讨论】:
就代码可读性而言,这个答案很可爱【参考方案2】:您可以在删除项目时简单地减少 i
。
var elements = [1, 5, 5, 3, 5, 2, 4];
var l = elements.length;
for(var i = 0; i < l; i++)
if(elements[i] == 5)
elements.splice(i, 1);
i--;
console.log(elements);
【讨论】:
【参考方案3】:使用Array.shift():
var array = [1, 2, 3, 'a', 'b', 'c'];
while (array.length > 0)
console.log(array.shift());
编辑:可能不符合规格。我误读了这个问题(仅删除 某些 元素)并且太急于添加尚未提及的方法...
【讨论】:
正如您在编辑中所说,这实际上并不能回答问题,但它确实回答了我试图搜索的问题。谢谢。【参考方案4】:您可以在这里使用filter
方法:
var elements = [1, 5, 5, 3, 5, 2, 4].filter(function(a)return a !== 5;);
//=> elements now [1,3,2,4]
或者如果你不想碰elements
:
var elementsfiltered
,elements = [1, 5, 5, 3, 5, 2, 4]
.filter( function(a)if (a!==5) this.push(a); return true;,
elementsfiltered = [] );
//=> elementsfiltered = [1,3,2,4], elements = [1, 5, 5, 3, 5, 2, 4]
filter
见 MDN documentation
您也可以扩展Array.prototype
Array.prototype.remove = Array.prototype.remove || function(val)
var i = this.length;
while(i--)
if (this[i] === val)
this.splice(i,1);
;
var elements = [1, 5, 5, 3, 5, 2, 4];
elements.remove(5);
//=> elements now [1,3,2,4]
【讨论】:
虽然创建一个新数组,过滤器确实是一个不错的解决方案,但 OP 实际上确实询问了关于删除内联元素的问题,最好举个例子。跨度> 似乎不必要地偏离了原始代码。 OP 可以通过在拼接后减少i
来保留他现有的代码。
我个人觉得过滤器更安全,因为递减我可能会导致边缘情况,就好像零元素存在等【参考方案5】:
这是使用Array.indexOf、while 和Array.splice 删除内联元素的示例。
var elements = [1, 5, 5, 3, 5, 2, 4];
var remove = 5;
var index = elements.indexOf(remove);
while (index !== -1)
elements.splice(index, 1);
index = elements.indexOf(remove);
console.log(elements);
开启jsfiddle
【讨论】:
低效 O(n^2) 算法被否决 我从来没有对效率提出任何要求,问题并不关心这一点,而是在执行内联元素删除时如何处理不断变化的数组长度。这是一个 jsPerf,以便您可以将高效版本作为答案并将其与发布的其他答案进行比较。 jsperf.com/soq-iterate-over-an-array-and-remove 处理数组长度变化的规范方法是从数组的末尾开始并向后工作。或者,如果您删除了当前元素,则可以从当前位置向前工作并且不增加。相反,每次找到匹配项时,您的方法从第零个元素开始,从而反复遍历相同的元素。这是一个非常糟糕的算法,永远不应该使用。 好吧,这很奇怪——我试过了,而且(在这个小样本集上)它慢得多。我还不知道为什么。 jsperf.com/soq-iterate-over-an-array-and-remove/2 我稍微更改了测试用例 - 现在 fromIndex 用例的运行速度非常轻微...jsperf.com/soq-iterate-over-an-array-and-remove/3【参考方案6】:从头开始!
var elements = [1, 5, 5, 3, 5, 2, 4];
for(var i = elements.length -1; i >= 0 ; i--)
if(elements[i] == 5)
elements.splice(i, 1);
【讨论】:
+1 用于从末尾开始,以避免由于 OP 提到的长度变化而跳过元素。for (var i = elements.length; i--;)
可能是更常见的写法。
我希望我能不止一次地对此表示赞同。奥卡姆正在向你发送一个来自伟大彼岸的宇宙高五。
认真的吗?一个 O(n^2) 的答案,有 147 个赞成票,没有反对票?这是给你的反对票。
这不只是 O(n) 吗?它只循环整个数组一次。以上是关于如何在 JavaScript 中迭代数组并删除元素 [重复]的主要内容,如果未能解决你的问题,请参考以下文章