編集:これは今のところ残しておきますが、_.flattenを完全に忘れていたので、redmallard's got a much better answer .
製品名がすでにわかっていて、それらがすべてのグループに表示されている場合は、次の方法ですべてをすばやく行うことができます。
var productAveragePrices = function ( groups, names ) {
return _.map( names, function ( name ) {
var product = { name: name }, productPricesSum = 0;
_.each( groups, function ( group ) {
productPricesSum += ( _.findWhere( group, product ).price );
});
product.price = productPricesSum / _.size( groups );
return product;
});
};
var foo2 = productAveragePrices = function ( foo, ['one', 'two'] );
これをまとめると、グループに異なる製品がある場合でも機能するはずです (たとえば、1 番目、2 番目、4 番目のグループでは「1」、1 番目と 3 番目のグループでは「2」)。
var productPriceReducer = function( memo, group ) {
_.each( group, function( product ) {
// Grabs the current product from the list we're compiling
var memoProduct = _.findWhere( memo, { name: product.name });
if ( !memoProduct ) {
// If the product doesn't exist, creates a holder for it and its prices
memoProduct = {
name: product.name,
prices: [ product.price ]
};
memo.push( memoProduct );
} else {
// Otherwise, it just adds the prices to the existing holder.
memoProduct.prices.push( product.price );
}
});
return memo;
};
// This gets us a list of products with all of their prices across groups
var productPrices = _.reduce( foo, productPriceReducer, [] );
// Then reducing to the average is pretty simple!
var productAveragePrices = _.map( productPrices, function ( product ) {
var sumPrices = _.reduce( product.prices, function ( memo, price ) {
return memo + price;
}, 0 );
return {
name: product.name,
price: sumPrices / product.prices.length
};
});
カウンターを使用して価格を合計する 1 つの関数で上記を実行することもできますが、この方法では、標準偏差を取得したりモードを見つけたりする場合に備えて、価格も取得できます。