从数组中删除一个元素的最快方法

40

如何快速从数组中删除一个特定条目?

这个数组很大,并且包含字符串。

我不仅仅想将 Array[5] 设为 null,而是希望数组大小减少一,并且 array[5] 应该有 array[6] 的内容。

5个回答

74

虽然没有任何基准测试来支持这个说法,但是人们会认为本地的Array.splice方法是最快的...

因此,要删除索引为5的条目:

array.splice(5, 1);

splice()确实是一个好方法,但要记住,在大数组中删除中间的元素会很慢,因为Flash将“向上移动”后面的条目以填补空白。 - grapefrukt
6
请注意,如果在遍历数组时从中间删除元素,除非您倒序遍历,否则会造成严重后果。 - Sean
4
对于关心被删除特定条目的价值的人,请记住splice返回一个数组,因此您需要使用array.splice(5, 1)[0]; - Alex Dean

36

如果您不关心数组中元素的顺序(但只是想让它变短1个),可以将数组的最后一个元素复制到要删除的索引处,然后弹出最后一个元素。

array[index] = array[array.length-1];
array.pop();

如果可以重新排列数组的顺序,我会猜测这种方法在CPU时间上更快。

编辑:你应该针对你特定的情况进行基准测试;我最近就是这样做的,只使用splice更快。(可能是因为Chrome实际上没有将数组存储为单个连续缓冲区。)


3
真聪明!比splice快得多,简直快得不可思议:http://jsperf.com/remove-element-splice-vs-move-and-pop - MaiaVictor
1
+1,要不考虑一行代码:array[index] = array.pop() 或者 array[index] = array[array.length-- -1] - Nikos M.
(array.length > 1) && (array[index] = array.pop()) || array.pop() - Nikos M.
1
@Sam 是的,它可能永远都会是这样。(哦,那时候我觉得自己很聪明的事情...) - MaiaVictor
"#MaiaVictor 它比切片还快吗?" @Sam 所以编译器(好吧,解释器。嗯...)的奇怪之处在于,如果有更聪明的处理过程的方法,它们最终会使用它。话虽如此,[一个编写不良的jsbench测试](https://jsbench.me/e3lf89o2g0/1)告诉我,`.pop`(此解决方案)仍然几乎是切片的两倍快([?](https://math.stackexchange.com/q/186730/842186))。`;^)` - ruffin
显示剩余2条评论

6

Array.splice() "向数组中添加和删除元素"

myArr.splice(indexToRemove, 1); // only removing one index, thus the 1

4

我测试了Array.prototype.splice()并发现对于大型数组来说它非常慢。

一种更快的删除元素的方法是将您要保留的元素复制到一个新数组中,同时跳过您要删除的元素。完成复制后,只需用新数组覆盖旧数组即可。

在我的测试中,我从包含100,000个项目的数组中每隔一个删除一个元素。该测试比较了Array.prototype.splice()和其他方法。以下是结果:

855 ms = splice
  7 ms = manual copying without preserving the original array
 14 ms = manual copying with preserving the original array

这是最后一种方法的代码:
var arrB = [],
    i=varA.length,
    j=0;

// copy even items to a new array
while(i > 0) {
    i-=2; // skip two elements
    arrB[j++] = arrA[i];
}

// clear the old array
arrA.splice(0, arrA.length);

// copy values back to the old array
// array is preserved (references to the array don't need to be updated)
arrA.push.apply(arrA, arrB);

在jsFiddle网站上可以看到测试实例:http://jsfiddle.net/sansegot/eXvgb/3/ 如果只需要移除一些元素,则结果会有很大不同,这种情况下Array.prototype.splice()更快(尽管差异不是很大)!只有当您需要多次调用splice()时,才值得实现自定义算法。第二个测试,其中要删除有限数量的元素,可以在此处找到:http://jsfiddle.net/sansegot/ZeEFJ/1/

2

根据您的情况,如果您想优先考虑性能,可以考虑使用字典而不是数组。

var dict:Dictionary = new Dictionary();

// The following value/key set should be customized so you can 
// get use of them in your specific case.

dict[item1] = item1;
dict[item2] = item2;

...

delete dict[item1];

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