从数组中删除最有效的方法?

时间:2015-02-08 22:39:00

标签: javascript arrays

我在HTML5游戏中有一个包含粒子(火,血,烟等)的数组。所有颗粒都具有有效期/寿命。我每帧以60fps创建多达100个粒子,所以我希望尽可能保持这个阵列的清洁,这样我就可以有效地循环它。

我听说使用&#c; splice'而不是删除'从数组中删除元素。这对我来说很有意义,因为我不想循环通过空白的数组键(删除'留下)。

然而,我测试了这一点,并且如果我删除'那么帧速率会更高,更一致。键而不是拼接它们以去除过期的粒子。缺点是游戏运行的时间越长,我的粒子阵列就越长。

有更好的解决方案吗?

3 个答案:

答案 0 :(得分:4)

如果数组中项目的顺序无关紧要,则只需将数组中的最后一项指定给要覆盖的项目,然后通过缩小.length将其删除。

function unordered_remove(arr, i) {
    if (i <= 0 || i >= arr.length) {
        return;
    }
    if (i < arr.length - 1) {
        arr[i] = arr[arr.length-1];
    }
    arr.length -= 1;
}

这要快得多,因为它不需要重新索引,并且适用于顺序无关紧要的情况。

答案 1 :(得分:2)

在数组元素上使用delete时,您实际所做的就是将该数组元素设置为undefined。该数组仍将具有相同的长度。当您使用splice时,您实际上完全删除了该元素。该元素被删除,并且该元素之后的所有内容都向下移动1个索引。对于这两个元素,delete将更快,因为您的数组不必重新索引。

至于性能,如果将已删除的元素保留为undefined,那么这可能是最好的方法。如果您担心数组长度增长太长,或者可能需要经常搜索该数组并希望减少开销,您可以定期filter出未定义的元素,如下所示:

function filterArr() {
    myArr = myArr.filter(function(v) {
       return typeof v !== 'undefined';
    });
}

var interval = setInterval(filterArr, 5000);

这将为您提供两全其美的体验。当您需要移除粒子时,可以使用delete将元素设置为undefined,这比在适当位置移除它们更快。你不时地将它们移除,以保持阵列尺寸更小。

您可以根据自己的要求进行改进。祝你好运:)

答案 2 :(得分:1)

通过自己打包数组,您将获得更高的性能:更少的操作,无需处理当前数组并创建新数组(如Array.filter所做的那样),因此垃圾收集更少。

function packArray(tgtArray) {
   if (!tgtArray || !tgtArray.length) return;
   var srcIndex = 0;
   var dstIndex = 0;
   var arrayLength = tgtArray.length ;
   do {
       var currentItem = tgtArray[srcIndex]; 
       if (currentItem.alive) {
         if (srcIndex != dstIndex) {
            tgtArray[dstIndex] = currentItem ;
         }
         dstIndex++;
       } 
       srcIndex++;
   } while (srcIndex != arrayLength) ;
    dstIndex--;
    tgtArray.length = dstIndex > 0 ? dstIndex : 0 ;
}