簡體   English   中英

使用JavaScript和lodash匯總對象數組數據的最佳方法

[英]Best way to summarize data for an array of objects using JavaScript and 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
    }]

我怎樣才能做到這一點?

這是一種方法,可能不是最快的方法,但是它可以工作並且不會產生任何臨時變量。 除了單個數組var name(r)之外,它沒有硬編碼到數據,不需要運行任何庫(在dino瀏覽器中除外),並且它是“簡單的”:

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
    }
*/

基本思想是提取每個鍵下的所有值,然后對這些值進行計數。 這種兩次通過的解決方案可能比硬編碼的單用途例程要慢一些,但是它消除了對手工編碼的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);

當然,根據需要,可以使用一些生成器功能來改善這一點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM