2017-04-12 100 views
2

我正在處理一個對象數組。每個對象都有兩個屬性,大小和數量。Javascript:比較數組元素的屬性,如果相同,組合

var drives = [ 
{size:"900GB", count:3}, 
{size:"900GB", count:100}, 
{size:"1200GB", count:5}, 
{size:"900GB", count:1} 
] 

我不喜歡相同的大小如何產生多次,並想將所有重複的大小成僅有1數組索引。

首先我有按大小排序的數組。然後我試着做一個for-loop來管理重複。

drives.sort(function(obj1, obj2) { 
var First = parseInt(obj1.size) 
var Second = parseInt(obj2.size) 
// Ascending: first size less than the previous 
return First - Second; 
}) 


for(var i = 0; i < drives.length-1; i++) 
{ 

    if(drives[i].size == drives[i+1].size) 
    { 
     drives[i+1].count+=drives[i].count; 
     //add the count of the first index to the second index's count 
     drives.splice(i, 1); 
     //delete the first index 
    } 
}   

https://jsbin.com/zayofiqoke/edit?js,console

的環路,似乎並不正確地迭代。它只結合了兩個索引。我如何實現我在找的東西?謝謝!

回答

0

編輯:使用Array#filter可能會更短。通過Nina Scholz發佈使用此策略的第一個答案。我正在使用filter函數的第二個參數,該函數將this設置爲傳遞迴調的上下文,以儘可能少地使用額外的行。

var drives = [ 
 
    {size:"900GB", count:3}, 
 
    {size:"900GB", count:100}, 
 
    {size:"1200GB", count:5}, 
 
    {size:"900GB", count:1} 
 
] 
 

 
var result = drives.filter(function (e) { 
 
    if (e.size in this) this[e.size].count += e.count 
 
    else return this[e.size] = e 
 
}, {}) 
 

 
console.log(result)


原文:一個更好的辦法可能是使用 Array#mapArray#reduce

var drives = [ 
 
    {size:"900GB", count:3}, 
 
    {size:"900GB", count:100}, 
 
    {size:"1200GB", count:5}, 
 
    {size:"900GB", count:1} 
 
] 
 

 
var map = drives.reduce(function (map, e) { 
 
    if (e.size in map) map[e.size].count += e.count 
 
    else map[e.size] = e 
 
    return map 
 
}, {}) 
 

 
var result = Object.keys(map).map(function (k) { 
 
    return this[k] 
 
}, map) 
 

 
console.log(result)

+0

偉大的編輯旋轉! – wajeezy

0

您可以過濾數組並使用哈希表上的閉包來更新相同大小的項目。

var drives = [{ size: "900GB", count: 3 }, { size: "900GB", count: 100 }, { size: "1200GB", count: 5 }, { size: "900GB", count: 1 }]; 
 

 
drives = drives.filter(function (hash) { 
 
    return function (a) { 
 
     if (!hash[a.size]) { 
 
      hash[a.size] = a; 
 
      return true; 
 
     } 
 
     hash[a.size].count += a.count; 
 
    }; 
 
}(Object.create(null))); 
 

 
console.log(drives);

+0

謝謝龔如心!這是一個非常好的解決方案。 – wajeezy

0

這可能不是最好的實現,但你可以始終保持元素的臨時列表,並遍歷它:

var tmp = {}; 
var out = []; 
for(var i = 0; i < drives.length; i++) { 
    if(!tmp[JSON.stringify(drives[i])]) { 
     out.push(drives[i]); 
     tmp[JSON.stringify(drives[i])] = true; 
    } 
} 

我做的是迭代通過數組,我將對象轉換爲JSON並將它用作對象中的鍵,所以如果有任何相同的對象,它們將被希望捕獲,因爲它們存在於臨時對象中(不斷查找〜O(1)stringify會迭代以上循環中的鍵)。

如果尚未定義密鑰,請將該對象推送到新數組並繼續到原始數組的末尾。

因此,您的最終解決方案運行在O(n),但它不是非常有效的內存。