繁体   English   中英

Javascript从Array中删除Object的最快方法

[英]Javascript fastest way to remove Object from Array

在应用程序工作在速度是至关重要的,该阵列是巨大的 包含在阵列中的对象。

我尝试使用grepfilter并且看不到明显的速度差异,变化+ - 5ms ,也尝试循环遍历数组并使用.splice(i,1); (结果相同)。

我有一台快速的机器,如果它在快速机器上总是需要或多或少的同时,这是否意味着在旧机器上需要或多或少相同的时间?

有没有更快的方法从数组中删除对象?

想要做这样的事情:

var filterTime = performance.now();
doStuff1();
var filterTimeEnd = performance.now();

var grepTime = performance.now();
doStuff2();
var grepTimeEnd = performance.now();

然后将差异存储在cookie中,以便下次加载或刷新页面时,执行最有效的方法:从数组中删除对象。

UPDATE

过滤器实验的片段

      companyMasters = companyMasters.filter(function (obj) {
      return obj.masterId != CompanyObj.masterId;
      });

您需要迭代数组以查找单个项目的任何解决方案似乎表明您正在使用的数据结构存在问题。 您可能应该将它们存储在一个对象中,而不是将对象存储在数字索引的数组中,其中键是您要尝试查找的masterId值。 至少,如果由于某些其他原因需要将对象保存在数字索引数组中,可以考虑构建一个单独的对象,在该对象中将masterId值映射到对象所在的主数组中的索引。

所以不是这样的:

[
    {
        masterId: 'foo',
        ...
    },
    {
        masterId: 'bar',
        ...
    },
    ...
]

您将构建这样的数据结构:

{
    foo: {
        masterId: 'foo',
        ...
    },
    bar: {
        masterId: 'bar',
        ...
    },
    ...
}

这将允许您的代码如下所示:

var needle = CompanyObj.masterId;
// delete object set for 'needle' property
delete companyMaster[needle];

这为您提供了O(1)时间复杂度而不是O(n)

现有的答案已经为降低底层问题的运行时复杂性提供了很好的解决方案。

但是我想简要回答原始问题,因为这是Google搜索如何以最高效的方式从数组中删除的第一页。

在不维护顺序的情况下, 通过索引删除的最快方法是通过将最后一个元素分配给要删除的索引并从数组中弹出来删除,因为这具有O(1)运行时复杂性。

Array.prototype.mySwapDelete = function arrayMySwapDelete (index) {
    this[index] = this[this.length - 1];
    this.pop();
}

通过维护订单按索引删除的最快方式是:

Array.prototype.myShiftDelete = function arrayMyShiftDelete (index) {
    var stop = this.length - 1;
    while (index < stop) {
        this[index] = this[++index];
    }

    this.pop();
}

我创建了一个JS perf片段来对不同的函数进行基准测试: https//jsperf.com/array-remove-by-index

当想要过滤时 ,比调用分配新数组的本机.filter()函数更快地进行过滤和移位。 这个就地过滤器也维持顺序:

Array.prototype.myShiftFilter = function arrayMyShiftFilter (predicate) {
    let i, j;

    for (i = 0, j = 0; i < this.length; ++i) {
        if (predicate(this[i])) {
            this[j] = this[i];
            ++j;
        }
    }

    while (j < this.length) {
        this.pop();
    }
}

另请参阅用于基准测试的JS Perf代码段: https//jsperf.com/array-filter-in-place

不是反复循环遍历数组以一次删除一个项目,而是构建一个可用于一次过滤掉所有项目的地图:

var map = {};
for (var i = 0; i < itemsToRemove.length; i++) {
  map[itemsToRemove[i]] = 1;
}

companyMasters = companyMasters.filter(function (obj) {
  return !(obj.masterId in map);
});

暂无
暂无

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

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