2015-05-18 44 views
2

在速度至關重要的應用程序上工作,陣列是巨大的數組中包含的對象。Javascript最快的方式從數組中刪除對象

我嘗試用grepfilter,不能看到顯著速度差,變化+ - 5ms的,還試圖通過陣列循環和使用.splice(i,1);(相同的結果)。

我有一臺快速的機器,如果它在快速機器上總是或多或少需要相同的時間,這是否意味着它將在舊機器上花費更多或更少的時間?

有更快的方法從數組中刪除對象嗎?

想要做這樣的事情:

​​

,然後存儲在cookie中的差異,所以下一次加載頁面或刷新,執行最有效的方法:從數組刪除對象。

UPDATE

過濾實驗的片段

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

大約有多少元素被你刪除與數組大小成正比? – twinlakes

+4

如果您使用的是grep&filter,那麼在這裏有更多的排列,而不僅僅是從數組中刪除一個對象。你應該把你的用例放進http:// jsperf。com和在多臺機器上測試 – CodingIntrigue

+0

@twinlakes我正在刪除一個數組中的對象,長度小於10 000,但它可能變得更大 – Jack

回答

10

中,你需要遍歷數組中找到一個項目的任何解決辦法似乎表明你有問題與您正在使用的數據結構。與其將對象存儲在數字索引數組中,或許應將其存儲在一個對象中,其中的鍵是要針對其進行查找的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)

+0

不幸的是,我必須保留數字索引數組:「建立一個單獨的對象,在其中你將masterId值映射到索引」不是一個壞主意 – Jack

+0

@Jack呃,除非你可以同時建立這個地圖您正在構建陣列,您真的需要考慮單獨的地圖是否合理。你將不得不循環數組來創建地圖(一個'O(n)'操作)。如果你只想從數組中刪除一個項目,你將不會真正獲得太多價值。但是如果你不得不刪除多個值,你仍然可能會看到好處。無論哪種方式,如果您需要循環查找數組,那麼在找到匹配項時應該建立一個休息時間以避開循環,因此您不必循環整個數組。 –

+2

如果數組是絕對必要的,我也會有一個像Mike Brant所示的地圖對象。除了id之外,這些對象還可以有一個索引,顯示如何快速到達並拼接出數組中的masterId。 *但是*,那麼你有問題需要更新所有的地圖的索引引用的數字在刪除之後。最終,是的......這就是數據庫存在的原因,甚至是JavaScript的原因;以更容易訪問的方式存儲事物。你的數組結構**會導致問題**。把這些信息傳達給誰來授權。 – Katana314

2

而是通過陣列一遍又一遍地循環一次刪除一個項目,建立一個地圖,你可以一次使用過濾掉所有的項目:

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

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

這是對原始文章中的代碼的重大改進,因爲至少您只循環數組一次,刪除所有需要的項目除去。分別循環瀏覽每個要移除的項目將是非常成問題的。 –