Skip to content Skip to sidebar Skip to footer

Find Average Value For Array Of Hashes Using Multiple Group By

based on Summarize array of objects and calculate average value for each unique object name I could partially solve my problem. I did group by ed_id but I need to group by ed_id an

Solution 1:

Methods/Functions used:

Array.prototype.reduce(callback[, initialValue]): The reduce() method applies a function against an accumulator and each value of the array (from left-to-right) to reduce it to a single value.

Object.prototype.keys(obj): The Object.keys() method returns an array of a given object's own enumerable properties, in the same order as that provided by a for...in loop (the difference being that a for-in loop enumerates properties in the prototype chain as well).

var data = [
  { ed_id: 1, el_id: 127, value: 2  },
  { ed_id: 1, el_id: 127, value: 6  },
  { ed_id: 1, el_id: 129, value: 3  },
  { ed_id: 1, el_id: 129, value: 13 },
  { ed_id: 2, el_id: 127, value: 5  },
  { ed_id: 2, el_id: 127, value: 9  },
  { ed_id: 2, el_id: 129, value: 10 }
]


// group the data
var groupedData = data.reduce(function(l, r) {
  // construct a unique key out of the properties we want to group by
  var key = r.ed_id + "|" + r.el_id;

  // check if the key is already known
  if (typeof l[key] === "undefined") {
    // init with an "empty" object
    l[key] = {
      sum: 0,
      count: 0
    };
  }
  
  // sum up the values and count the occurences
  l[key].sum += r.value;
  l[key].count += 1;

  return l;
}, {});

console.log(JSON.stringify(groupedData));
//{"1|127":{"sum":8,"count":2},"1|129":{"sum":16,"count":2},"2|127":{"sum":14,"count":2},"2|129":{"sum":10,"count":1}}


// calculate the averages
var avgGroupedData = Object.keys(groupedData)
  // iterate over the elements in <groupedData> and transform them into the "old" format
  .map(function(key) {
    // split the constructed key to get the parts
    var keyParts = key.split(/\|/);

    // construct the "old" format including the average value
    return {
      ed_id: parseInt(keyParts[0], 10),
      el_id: parseInt(keyParts[1], 10),
      value: (groupedData[key].sum / groupedData[key].count)
    };
  });

console.log(JSON.stringify(avgGroupedData));
// [{"ed_id":1,"el_id":127,"value":4},{"ed_id":1,"el_id":129,"value":8},{"ed_id":2,"el_id":127,"value":7},{"ed_id":2,"el_id":129,"value":10}]

Solution 2:

This should do what you want. Broken down into small functions for readability:

var groupingKey = function(item){
    return item.ed_id + "/" + item.el_id
}

var sum = function(total, item){
    return total + item.value;
}

var average = function(items){
    return _.reduce(items, sum, 0) / items.length;
}

var groupsToResult = function(groups){

    return {
        ed_id: groups[0].ed_id,
        el_id: groups[0].el_id,
        value: average(groups)
    }
}

var result = _.chain(a)
    .groupBy(groupingKey)
    .map(groupsToResult)
    .value();

Post a Comment for "Find Average Value For Array Of Hashes Using Multiple Group By"