2014-10-21 50 views
0

我有一個對象數組,我正在尋找最好的最有效的方式來分組和總結數據。目前,我有幾百行代碼和大量'對於每個'涉及的語句,我知道有很多簡單的方法來做到這一點,但我無法讓它工作。使用JavaScript和lodash彙總對象數組的數據的最佳方法

這是我的數據的一個小樣本。對於任何給定的數據集,我可能會有幾百種產品。每個產品有五顆星,並且星星可以分配三個值中的一個(已獲得,未獲得或正在進行)。我的目標是查看每個星號有多少個值被分配給每個星的總結。

[{ 
    Product: "A" 
    star1: "Not Earned" 
    star2: "In Progress" 
    star3: "Earned" 
    star4: "Not Earned" 
    star5: "In Progress" 
},{ 
    Product: "B" 
    star1: "In Progress" 
    star2: "Not Earned" 
    star3: "In Progress" 
    star4: "Earned" 
    star5: "Earned" 
}] 

最後,我會看,結果是這樣的:我知道我的對象和數組的格式是斷位,它是其中一個原因更有部分爲什麼我尋求幫助。我也在使用JavaScript和lodash。

Results= [{ 
    star1:{ 
     In Progress: 50, 
     Not Earned: 32, 
     Earned: 1 
    },{ 
    star2:{ 
     In Progress: 10 
     Not Earned: 14, 
     Earned: 11 
    },{ 
    star3:{ 
     In Progress: 45, 
     Not Earned: 25, 
     Earned: 19 
    }] 

我該怎麼做?

+0

我不認爲所有這些數字都來自.. – elclanrs 2014-10-21 21:41:20

+0

那麼還有更多的產品,那些是和? – elclanrs 2014-10-21 21:43:13

+0

「對於任何給定的數據集,我可能會有幾百種產品。」如果只有數百個,你可以在世界上沒有最快速的方法的情況下做到漂亮/懶惰,這聽起來像是對下劃線的一種很好的使用。 – dandavis 2014-10-21 21:43:29

回答

1

下面是一種方法來做到這一點,可能不是最快的,但它的工作原理並不會產生任何臨時變量。這不是硬編碼到多單數組變量名稱(R)以外的數據,不需要任何庫運行(除恐龍瀏覽器),和它的「簡單」:

var r=[{ 
    Product: "A", 
    star1: "Not Earned", 
    star2: "In Progress", 
    star3: "Earned", 
    star4: "Not Earned", 
    star5: "Earned" 
},{ 
    Product: "B", 
    star1: "In Progress", 
    star2: "Not Earned", 
    star3: "In Progress", 
    star4: "Earned", 
    star5: "Earned" 
},,{ 
    Product: "C", 
    star1: "In Progress", 
    star2: "Not Earned", 
    star3: "Not Earned", 
    star4: "Earned", 
    star5: "In Progress" 
}]; 

var sums = {}; // A count holder 

Object.keys(r[0]).forEach(function(k){ // For each key in the data of a single data object 
    this[k]=r.map(function(o){ return o[k] }) // Pluck values 
     .map(function(w){ 
      if(this[w]){this[w]++;}else{this[w]=1;} // Count values using an object 
      return this; 
     },{}).pop(); // Take just one of the count object copies (poor-man's reduce with this) 
}, sums); 

// View result: 
JSON.stringify(sums, null, "\t") 
/* == { 
    "Product": { 
     "A": 1, 
     "B": 1, 
     "C": 1 
    }, 
    "star1": { 
     "Not Earned": 1, 
     "In Progress": 2 
    }, 
    "star2": { 
     "In Progress": 1, 
     "Not Earned": 2 
    }, 
    "star3": { 
     "Earned": 1, 
     "In Progress": 1, 
     "Not Earned": 1 
    }, 
    "star4": { 
     "Not Earned": 1, 
     "Earned": 2 
    }, 
    "star5": { 
     "Earned": 2, 
     "In Progress": 1 
    } 
*/ 

的基本思路將採集每個鍵下的所有值,然後對這些值進行計數。 這種雙通解決方案可能比硬編碼單通道例程慢一點,但它不需要手動編碼縮減功能。

可以在零如果需要違約,我不知道,如果這兩個例子對象包含所有的集合包含的可能值...

+0

+1做一個通用問題的通用解決方案。請記住,使用純JavaScript時,實現可以並且會有所不同。環境一致性就是爲什麼我選擇堅持問題中提到的lodash庫。 – psaxton 2014-10-21 22:13:55

+0

在支持它們的瀏覽器中,Object.keys(),[] .forEach和[] .map()的行爲都是相同的,對於不符合規範的瀏覽器,polyfills也是如此。下劃線/ lodash對於非泛型迭代中的速度是有利的(參見http://danml.com/mofun/#Performance上的\ _。map和U.map與r.map相比)以及\ _。isArray( ),但核心數組迭代方法imho在香草中「足夠好」以用於生產。 – dandavis 2014-10-21 22:23:57

+0

這是一個讚美和upvote,@ JSilva似乎無法召集:)感謝您的鏈接。你的mofun庫看起來很乾淨。 – psaxton 2014-10-22 14:48:26

0

您正在查找「reduce」功能。

像下面這樣的東西應該支付賬單。

var products = [{ 
    Product: "A", 
    star1: "Not Earned", 
    star2: "In Progress", 
    star3: "Earned", 
    star4: "Not Earned", 
    star5: "In Progress", 
},{ 
    Product: "B", 
    star1: "In Progress", 
    star2: "Not Earned", 
    star3: "In Progress", 
    star4: "Earned", 
    star5: "Earned", 
}]; 

function countStars(accumulator, product) { 
    for(var prop in accumulator) { 
     accumulator[prop][product[prop]] += 1; 
    }; 

    return accumulator; 
} 

var starTemplate = { 
    "In Progress": 0, 
    "Not Earned": 0, 
    "Earned": 0, 
}; 

var initialAccumulator = { 
    star1: _.clone(starTemplate), 
    star2: _.clone(starTemplate), 
    star3: _.clone(starTemplate), 
    star4: _.clone(starTemplate), 
    star5: _.clone(starTemplate), 
}; 


var result = _.reduce(products, countStars, initialAccumulator); 

當然這一點可以與根據需要幾個發電機的功能得到改善。

相關問題