基于Summarize array of objects and calculate average value for each unique object name我可以部分解决我的问题。我按 ed_id 进行分组,但我需要按 ed_id 进行分组,然后 el_id ,并根据这些分组得到平均值,所以这里是我的哈希数组:
a = [
{
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
}
]
所以最后的哈希数组需要看起来像:
b = [
{
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
}
]
谢谢!
答案 0 :(得分:1)
使用的方法/功能:
Array.prototype.reduce(callback[, initialValue])
: reduce()方法对累加器和数组的每个值(从左到右)应用一个函数,将其减少为单个值。 < / p>
Object.prototype.keys(obj)
: Object.keys()方法返回给定对象自身的可枚举属性的数组,其顺序与for ... in循环提供的顺序相同(不同之处在于for-in循环也枚举了原型链中的属性。
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}]
&#13;
答案 1 :(得分:1)
这应该做你想要的。细分为小功能以便于阅读:
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();