vin*_*ork 8 javascript reduce mapreduce map underscore.js
我想将此对象简化为包含产品名称和平均价格的对象.最快的方法是什么?
var foo = { group1: [
{
name: "one",
price: 100
},
{
name: "two",
price: 100
}],
group2: [
{
name: "one",
price: 200
},
{
name: "two",
price: 200
}],
group3: [
{
name: "one",
price: 300
},
{
name: "two",
price: 300
}]
}
Run Code Online (Sandbox Code Playgroud)
导致
var foo2 = [{
name: 'one',
price: 200
},{
name: 'two',
price: 200
}];
Run Code Online (Sandbox Code Playgroud)
谢谢!
red*_*ard 20
在Evan的游行中不要下雨,但是这里有一个更短的选择;)
result = _.chain(original)
.flatten()
.groupBy(function(value) { return value.name; })
.map(function(value, key) {
var sum = _.reduce(value, function(memo, val) { return memo + val.price; }, 0);
return {name: key, price: sum / value.length};
})
.value();
Run Code Online (Sandbox Code Playgroud)
看到它的实际效果:http://plnkr.co/edit/lcmZoLkrlfoV8CGN4Pun?p = preview
我真的很喜欢 redmallard 的解决方案,但我想打一点高尔夫球。
Underscore 不包含sum
函数,但我们可以通过添加一个sum
mixin来编写非常优雅的函数表达式。这个函数在 underscore-contribs repo 中被称为add。
然后我们可以写:
// Somewhere in the initialization of the program
_.mixin({
sum : function (arr) {
return _.reduce(arr, function (s, x) { return s + x;}, 0);
}
});
result = _.chain(original)
.flatten()
.groupBy('name') // shorthand notation
.map(function (value, key) {
var sum = _.chain(value).pluck('price').sum().value();
return { name: key, price: sum / value.length};
})
.value();
Run Code Online (Sandbox Code Playgroud)
http://plnkr.co/edit/ul3odB7lr8qwgVIDOtM9
但是我们也可以创建一个avg
mixin 来扩展我们的工具带:
// Somewhere in the initialization of the program
_.mixin({
sum : function (arr) {
return _.reduce(arr, function (s, x) { return s + x;}, 0);
},
avg : function (arr) {
return _.sum(arr)/arr.length;
}
});
result = _.chain(original)
.flatten()
.groupBy('name') // shorthand notation
.map(function (value, key) {
return { name: key, price: _.avg(value)};
})
.value();
Run Code Online (Sandbox Code Playgroud)
编辑:暂时保留这个,但我完全忘记了 _.flatten,所以 redmallard 得到了更好的答案。
如果您已经知道产品名称并且它们出现在每个组中,您可以通过以下方式快速完成整个操作:
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'] );
Run Code Online (Sandbox Code Playgroud)
我将其放在一起,即使您的组有不同的产品(例如,第一组、第二组和第四组中的“一个”,第一组和第三组中的“两个”),它也应该起作用:
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
};
});
Run Code Online (Sandbox Code Playgroud)
您仍然可以使用计数器在一个函数中执行上述操作并对价格求和,但这样,您还可以获得价格,以防您想要计算标准差或找到众数。
归档时间: |
|
查看次数: |
10840 次 |
最近记录: |