2016-01-23 43 views
0

根据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

如果可以按'ed_id'它不应该是比较麻烦,那么组的结果通过'el_id' – Andreas

+0

我敢肯定,这不是一个大的麻烦,但我有麻烦解决这个 – Mil

回答

1

方法/函数使用:

Array.prototype.reduce(callback[, initialValue])的减少()方法应用于对一个储液器的功能和所述阵列的每一值(从左到右),以将其降低到一个值。

Object.prototype.keys(obj)的Object.keys()方法返回在给定对象的自己的枚举的属性的阵列,在相同的顺序,通过提供一种用于... 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}]

+0

这工作!谢谢! – Mil

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();