减少键上的对象数组并将值求和到数组中
Reduce array of objects on key and sum value into array
我有以下对象:
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 },
];
并使用了 lodash 地图:
result = _.map(data, function item, idx){
return {
key: item[key],
values: item.value,
}
}
这导致:
[
{ key: foo, val: 9 },
{ key: foo, val: 3 },
{ key: bar, val: 4 },
{ key: bar, val: 7 },
]
但现在我正在尝试 return:
[
{ key: 'foo', val: 12 },
{ key: 'bar', val: 11 },
]
我尝试使用 reduce,它似乎只输出到单个对象,然后我可以将其转换回数组,但我觉得必须有一种优雅的方式来使用 lodash 从我的源数据直接转到我想要的结果没有所有的中间步骤。
我认为 正在解决我的确切问题,但将对象转换为上面概述的所需对象数组似乎需要大量工作。
干杯。
有趣的是,这不是直截了当的,因为想通过键累加值,但又希望键作为 属性 键的值。所以有点像逆映射减少:
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();
为了 es6 的简洁性:
_.chain(data)
.reduce((memo, obj) => {
memo[obj.name = obj.val] += obj.val;
return memo;
}, {})
.map((val, key) => ({key, val}))
.value();
对使用 groupBy 而不是 reduce 进行初始分组的已接受答案的扭曲:
var result = _.chain(data)
.groupBy('name')
.map((group, key) => ({ key, val : _.sumBy(group, 'val') }))
.value();
您可以使用 map() and uniq(), and then map() each name to get their respective sums using sumBy().
获得所有独特的 names
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>
这里是非es6版本:
var result = _(data)
.map('name')
.uniq()
.map(function(key) {
return {
key: key,
val: _(data).filter({ name: key }).sumBy('val')
};
})
.value();
这是一个简单的非 lodash 版本。
const 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
},
]
const result = data.reduce((acc, curr) => {
const index = acc.findIndex(item => item.name === curr.name)
index > -1 ? acc[index].val += curr.val : acc.push({
name: curr.name,
val: curr.val
})
return acc
}, [])
console.log(result)
我有以下对象:
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 },
];
并使用了 lodash 地图:
result = _.map(data, function item, idx){
return {
key: item[key],
values: item.value,
}
}
这导致:
[
{ key: foo, val: 9 },
{ key: foo, val: 3 },
{ key: bar, val: 4 },
{ key: bar, val: 7 },
]
但现在我正在尝试 return:
[
{ key: 'foo', val: 12 },
{ key: 'bar', val: 11 },
]
我尝试使用 reduce,它似乎只输出到单个对象,然后我可以将其转换回数组,但我觉得必须有一种优雅的方式来使用 lodash 从我的源数据直接转到我想要的结果没有所有的中间步骤。
我认为
干杯。
有趣的是,这不是直截了当的,因为想通过键累加值,但又希望键作为 属性 键的值。所以有点像逆映射减少:
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();
为了 es6 的简洁性:
_.chain(data)
.reduce((memo, obj) => {
memo[obj.name = obj.val] += obj.val;
return memo;
}, {})
.map((val, key) => ({key, val}))
.value();
对使用 groupBy 而不是 reduce 进行初始分组的已接受答案的扭曲:
var result = _.chain(data)
.groupBy('name')
.map((group, key) => ({ key, val : _.sumBy(group, 'val') }))
.value();
您可以使用 map() and uniq(), and then map() each name to get their respective sums using sumBy().
获得所有独特的names
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>
这里是非es6版本:
var result = _(data)
.map('name')
.uniq()
.map(function(key) {
return {
key: key,
val: _(data).filter({ name: key }).sumBy('val')
};
})
.value();
这是一个简单的非 lodash 版本。
const 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
},
]
const result = data.reduce((acc, curr) => {
const index = acc.findIndex(item => item.name === curr.name)
index > -1 ? acc[index].val += curr.val : acc.push({
name: curr.name,
val: curr.val
})
return acc
}, [])
console.log(result)