问题
I have the following object:
data = [
{ name: 'foo', type: 'fizz', val: 9 },
{ name: 'foo', type: 'buzz', val: 3 },
{ name: 'bar', type: 'fizz', val: 4 },
{ name: 'bar', type: 'buzz', val: 7 },
];
And used lodash map:
result = _.map(data, function item, idx){
return {
key: item[key],
values: item.value,
}
}
Which results in:
[
{ key: foo, val: 9 },
{ key: foo, val: 3 },
{ key: bar, val: 4 },
{ key: bar, val: 7 },
]
but now I'm trying to return:
[
{ key: 'foo', val: 12 },
{ key: 'bar', val: 11 },
]
I tried using reduce which seems to only output to a single object, which I could then convert back into an array, but I feel like there must be an elegant way to use lodash to go from my source data straight to my desired result without all of the intermediate steps.
I thought this was addressing my exact problem, but it seems like quite a bit of work just to have to convert the object into the desired array of objects outlined above.
Cheers.
回答1:
Interestingly not straight forward, because of wanting to accumulate the value by key, but then wanting the key as a value of the property key. So somewhat like an inverse map reduce:
var result =
_.chain(data)
.reduce(function(memo, obj) {
if(typeof memo[obj.name] === 'undefined') {
memo[obj.name] = 0;
}
memo[obj.name] += obj.val;
return memo;
}, {})
.map(function (val, key) {
return {key: key, val: val};
})
.value();
For the sake of brevity in es6:
_.chain(data)
.reduce((memo, obj) => {
memo[obj.name = obj.val] += obj.val;
return memo;
}, {})
.map((val, key) => ({key, val}))
.value();
回答2:
A twist to the accepted answer that uses groupBy instead of reduce to do the initial grouping:
var result = _.chain(data)
.groupBy('name')
.map((group, key) => ({ key, val : _.sumBy(group, 'val') }))
.value();
回答3:
You can get all the unique names
using map() and uniq(), and then map() each name to get their respective sums using sumBy().
var result = _(data)
.map('name')
.uniq()
.map(key => ({
key,
val: _(data).filter({ name: key }).sumBy('val')
}))
.value();
var data = [
{ name: 'foo', type: 'fizz', val: 9 },
{ name: 'foo', type: 'buzz', val: 3 },
{ name: 'bar', type: 'fizz', val: 4 },
{ name: 'bar', type: 'buzz', val: 7 }
];
var result = _(data)
.map('name')
.uniq()
.map(key => ({
key,
val: _(data).filter({ name: key }).sumBy('val')
}))
.value();
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.js"></script>
Here is a non es6 version:
var result = _(data)
.map('name')
.uniq()
.map(function(key) {
return {
key: key,
val: _(data).filter({ name: key }).sumBy('val')
};
})
.value();
来源:https://stackoverflow.com/questions/37600093/reduce-array-of-objects-on-key-and-sum-value-into-array