Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/425.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript从数组中删除对象的最快方法_Javascript_Jquery_Arrays_Performance - Fatal编程技术网

Javascript从数组中删除对象的最快方法

Javascript从数组中删除对象的最快方法,javascript,jquery,arrays,performance,Javascript,Jquery,Arrays,Performance,在速度至关重要的应用程序上工作时,数组是巨大的,数组中包含的对象也是巨大的 companyMasters = companyMasters.filter(function (obj) { return obj.masterId != CompanyObj.masterId; }); 我尝试了和,但看不到明显的速度差异,变化+-5ms,还尝试了通过数组循环并使用.splice(I,1)(结果相同) companyMasters = companyM

在速度至关重要的应用程序上工作时,数组是巨大的,数组中包含的对象也是巨大的

      companyMasters = companyMasters.filter(function (obj) {
      return obj.masterId != CompanyObj.masterId;
      });
我尝试了和,但看不到明显的速度差异,变化+-5ms,还尝试了通过数组循环并使用
.splice(I,1)(结果相同)

      companyMasters = companyMasters.filter(function (obj) {
      return obj.masterId != CompanyObj.masterId;
      });
我有一台快速机器,如果它在快速机器上花费的时间或多或少相同,这是否意味着在旧机器上花费的时间或多或少相同

      companyMasters = companyMasters.filter(function (obj) {
      return obj.masterId != CompanyObj.masterId;
      });
有没有更快的方法从数组中删除对象

      companyMasters = companyMasters.filter(function (obj) {
      return obj.masterId != CompanyObj.masterId;
      });
想做这样的事情:

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

var grepTime = performance.now();
doStuff2();
var grepTimeEnd = performance.now();
      companyMasters = companyMasters.filter(function (obj) {
      return obj.masterId != CompanyObj.masterId;
      });
[
    {
        masterId: 'foo',
        ...
    },
    {
        masterId: 'bar',
        ...
    },
    ...
]
{
    foo: {
        masterId: 'foo',
        ...
    },
    bar: {
        masterId: 'bar',
        ...
    },
    ...
}
var needle = CompanyObj.masterId;
// delete object set for 'needle' property
delete companyMaster[needle];
然后将差异存储在cookie中,以便下次加载或刷新页面时,执行最有效的方法:从数组中删除对象

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

      companyMasters = companyMasters.filter(function (obj) {
      return obj.masterId != CompanyObj.masterId;
      });
过滤实验片段

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

任何需要迭代数组以查找单个项的解决方案似乎都表明您使用的数据结构有问题。与其将对象存储在数字索引数组中,不如将它们存储在一个对象中,其中键是您将尝试查找的
masterId
值。最起码,如果您需要将对象放在数值索引数组中,出于其他原因,可以考虑建立一个单独的对象,在该对象中,将代码< > MistID/<代码>值映射到对象驻留的主数组中的索引。
      companyMasters = companyMasters.filter(function (obj) {
      return obj.masterId != CompanyObj.masterId;
      });
因此,与此不同的是:

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

var grepTime = performance.now();
doStuff2();
var grepTimeEnd = performance.now();
      companyMasters = companyMasters.filter(function (obj) {
      return obj.masterId != CompanyObj.masterId;
      });
[
    {
        masterId: 'foo',
        ...
    },
    {
        masterId: 'bar',
        ...
    },
    ...
]
{
    foo: {
        masterId: 'foo',
        ...
    },
    bar: {
        masterId: 'bar',
        ...
    },
    ...
}
var needle = CompanyObj.masterId;
// delete object set for 'needle' property
delete companyMaster[needle];
您可以这样构建数据结构:

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

var grepTime = performance.now();
doStuff2();
var grepTimeEnd = performance.now();
      companyMasters = companyMasters.filter(function (obj) {
      return obj.masterId != CompanyObj.masterId;
      });
[
    {
        masterId: 'foo',
        ...
    },
    {
        masterId: 'bar',
        ...
    },
    ...
]
{
    foo: {
        masterId: 'foo',
        ...
    },
    bar: {
        masterId: 'bar',
        ...
    },
    ...
}
var needle = CompanyObj.masterId;
// delete object set for 'needle' property
delete companyMaster[needle];
这将允许您的代码如下所示:

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

var grepTime = performance.now();
doStuff2();
var grepTimeEnd = performance.now();
      companyMasters = companyMasters.filter(function (obj) {
      return obj.masterId != CompanyObj.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)

的操作,而不是一次通过数组循环删除一个项目,而是构建一个可以用于一次过滤所有项目的映射:

      companyMasters = companyMasters.filter(function (obj) {
      return obj.masterId != CompanyObj.masterId;
      });
var map = {};
for (var i = 0; i < itemsToRemove.length; i++) {
  map[itemsToRemove[i]] = 1;
}

companyMasters = companyMasters.filter(function (obj) {
  return !(obj.masterId in map);
});
var-map={};
对于(var i=0;i
现有答案已经为降低潜在问题的运行时复杂性提供了很好的解决方案

      companyMasters = companyMasters.filter(function (obj) {
      return obj.masterId != CompanyObj.masterId;
      });
然而,我也想简单地回答最初的问题,因为这是谷歌搜索如何以最高效的方式从数组中删除的第一页

      companyMasters = companyMasters.filter(function (obj) {
      return obj.masterId != CompanyObj.masterId;
      });
在不维护顺序的情况下按索引删除的最快方法是将最后一个元素指定给要删除的索引并从数组中弹出,因为这具有O(1)运行时复杂性

      companyMasters = companyMasters.filter(function (obj) {
      return obj.masterId != CompanyObj.masterId;
      });
Array.prototype.mySwapDelete = function arrayMySwapDelete (index) {
    this[index] = this[this.length - 1];
    this.pop();
}
通过维持秩序按索引删除的最快方法是移动到位:

      companyMasters = companyMasters.filter(function (obj) {
      return obj.masterId != CompanyObj.masterId;
      });
Array.prototype.myShiftDelete = function arrayMyShiftDelete (index) {
    var stop = this.length - 1;
    while (index < stop) {
        this[index] = this[++index];
    }

    this.pop();
}

另请参见基准测试的JS Perf代码片段:

大致删除多少元素与数组大小成比例?如果使用grep&filter,这里的排列方式比简单地从数组中删除对象要多。您应该使用您的用例,将其放入一个测试环境中,并在多个测试环境中进行测试machines@twinlakes我正在移除数组中的一个对象,长度小于10000,但它可能会变得更大。您是要从数组中只移除一个项目,还是一次移除一个项目?什么决定了应该删除哪些项目?@Jack这取决于你的应用程序需要以及你如何使用数组,但如果你没有使用数组,而是使用对象,其中key是对象ID,value是对象本身,该怎么办。然后删除一个对象就是删除对象。objectId应该像闪电一样快。不幸的是,另一方面,我必须保留数字索引数组:“构建一个单独的对象,在其中将masterId值映射到索引”这不是一个坏消息idea@Jack除非您可以在构建阵列的同时构建该映射,否则您将真正需要考虑单独的映射是否有意义。首先,您必须循环数组来构建映射(一个
O(n)
操作)。如果您只打算从数组中删除一项,那么您将不会获得太多价值。但如果您必须删除多个值,您可能仍然会看到好处。无论哪种方式,如果需要循环数组进行查找,您应该在找到匹配项时构建一个中断以跳出循环,这样您就不必循环整个数组。如果数组是绝对必要的,我还将有一个map对象,如Mike Brant所示。除了ID之外,这些对象还可以有一个索引,显示如何快速到达并拼接阵列中的masterId。但是,您有一个问题,即需要更新地图的所有索引引用,以查找删除的编号之后的编号。最终,是的……这就是数据库存在的原因,即使是JavaScript类型的数据库;以更方便的方式储存物品。您的阵列结构将导致问题。把这些信息交给授权的人。@Jack事实上,在进一步思考map方法时,我看不出你会从中获得我最初认为的好处。如果要从数组中删除项,则意味着您需要在每次删除更改映射到新索引值后更新映射对象(因为这些值会随着删除而更改)。这需要在地图上进行迭代,因此不会获得很大的好处。因此,即使您必须获取数组作为输入,您最好还是从数组中构造我在回答中提到的对象,然后丢弃该数组。@MikeBrant是的,这是真的创建一个映射只需要一段时间,构造对象并丢弃数组的麻烦要小得多。Katana314说,数据库可能比预期的用户机器处理它更快、更稳定,也许MongoDB这是对原始帖子中代码的一个重大改进,因为至少你只循环数组一次,删除所有需要删除的项。循环通过
      companyMasters = companyMasters.filter(function (obj) {
      return obj.masterId != CompanyObj.masterId;
      });