简体   繁体   English

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

[英]Javascript fastest way to remove Object from Array

Working on app where speed is crucial, the arrays are huge and the objects contained within the arrays. 在应用程序工作在速度是至关重要的,该阵列是巨大的 包含在阵列中的对象。

I experimented with grep and filter and can not see significant speed difference, varies +- 5ms , also tried looping through array and using .splice(i,1); 我尝试使用grepfilter并且看不到明显的速度差异,变化+ - 5ms ,也尝试循环遍历数组并使用.splice(i,1); (same results). (结果相同)。

I have a fast machine, if it always take more or less the same time on fast machine, does that mean it will take more or less same time on older machine? 我有一台快速的机器,如果它在快速机器上总是需要或多或少的同时,这是否意味着在旧机器上需要或多或少相同的时间?

Is there faster way to remove an object from array? 有没有更快的方法从数组中删除对象?

Want to do something like this: 想要做这样的事情:

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

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

and then store the differences in cookie, so the next time the page loads or is refreshed, execute most efficient way: removing object from array. 然后将差异存储在cookie中,以便下次加载或刷新页面时,执行最有效的方法:从数组中删除对象。

UPDATE UPDATE

snippet of filter experiment 过滤器实验的片段

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

Any solution in which you need to iterate the array to find a single item would seem to indicate that you have a problem with the data structure you are using. 您需要迭代数组以查找单个项目的任何解决方案似乎表明您正在使用的数据结构存在问题。 Rather than storing your objects in a numerically indexed array, perhaps your should be storing them in an object where keys are the masterId values that you are going to be trying to do lookups against. 您可能应该将它们存储在一个对象中,而不是将对象存储在数字索引的数组中,其中键是您要尝试查找的masterId值。 At a very minimum, if you need to keep your objects in a numerically index array for some other reason, you could consider building a separate object within which you map the masterId values to the index in the main array where the object resides. 至少,如果由于某些其他原因需要将对象保存在数字索引数组中,可以考虑构建一个单独的对象,在该对象中将masterId值映射到对象所在的主数组中的索引。

So rather than something like this: 所以不是这样的:

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

You would build your data structure like this: 您将构建这样的数据结构:

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

This would allow your code to look like this: 这将允许您的代码如下所示:

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

This gives you an operation with O(1) time complexity instead of O(n) . 这为您提供了O(1)时间复杂度而不是O(n)

The existing answer already provide good solutions to reducing the runtime complexity of the underlying problem. 现有的答案已经为降低底层问题的运行时复杂性提供了很好的解决方案。

However I want to briefly answer the original question as well, since this is the first page when googling for how to remove from an array the most performant way. 但是我想简要回答原始问题,因为这是Google搜索如何以最高效的方式从数组中删除的第一页。

Without maintaining order the fastest way to remove by index is removing by assigning the last element to the to be removed index and popping from the array, since this has O(1) runtime complexity. 在不维护顺序的情况下, 通过索引删除的最快方法是通过将最后一个元素分配给要删除的索引并从数组中弹出来删除,因为这具有O(1)运行时复杂性。

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

With maintaining order the fastest way to remove by index is shifting in place: 通过维护订单按索引删除的最快方式是:

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

    this.pop();
}

I have created a JS perf snippet to benchmark the different functions: https://jsperf.com/array-remove-by-index 我创建了一个JS perf片段来对不同的函数进行基准测试: https//jsperf.com/array-remove-by-index

When wanting to filter , it is also significantly faster to filter in place and shift than calling the native .filter() function, which allocates a new array. 当想要过滤时 ,比调用分配新数组的本机.filter()函数更快地进行过滤和移位。 This in place filter also maintains order: 这个就地过滤器也维持顺序:

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();
    }
}

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

Instead of looping through the array over and over to remove one item at a time, build a map that you can use to filter out all the items at once: 不是反复循环遍历数组以一次删除一个项目,而是构建一个可用于一次过滤掉所有项目的地图:

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