我有一个这样的数组:
[{
id: 1,
amount: 10,
date: '21/01/2017'
},{
id: 1,
amount: 10,
date: '21/01/2017'
},{
id: 1,
amount: 30,
date: '22/01/2017'
},{
id: 2,
amount: 10,
date: '21/01/2017'
},]
我希望输出如下:
{
'21/01/2017': {
1: {
amount: 20
},
2: {
amount: 10
}
},
'22/01/2017': {
1: {
amount: 30
}
}
}
基本上按数据分组,按id嵌套分组,同时汇总相关金额。
到目前为止,我已尝试使用reduce,并查看了lodash函数,但一直没有成功。 Reduce使得分组和求和很容易,但我找不到一种优雅的方法来创建第二级。我创建了一个沙箱来演示:
https://codesandbox.io/s/woj9xz6nq5
const dataToConsolidate = [{
id: 1,
amount: 10,
date: '21/01/2017'
}, {
id: 1,
amount: 10,
date: '21/01/2017'
}, {
id: 1,
amount: 30,
date: '22/01/2017'
}, {
id: 2,
amount: 10,
date: '21/01/2017'
},]
export const consolidate = (data) => {
const result = data.reduce(function (res, obj) {
(!(obj.date in res)) ?
res.__array.push(res[obj.date] = obj) :
res[obj.date].amount += obj.amount;
return res;
}, { __array: [] });
return result;
};
console.log(consolidate(dataToConsolidate))
答案 0 :(得分:5)
您可以将对象作为哈希表,并使用默认样式添加属性。
var array = [{ id: 1, amount: 10, date: '21/01/2017' }, { id: 1, amount: 10, date: '21/01/2017' }, { id: 1, amount: 30, date: '22/01/2017' }, { id: 2, amount: 10, date: '21/01/2017' }],
result = {};
array.forEach(function (o) {
result[o.date] = result[o.date] || {};
result[o.date][o.id] = result[o.date][o.id] || { amount: 0 };
result[o.date][o.id].amount += o.amount;
});
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 1 :(得分:3)
这是使用reduce
的相对ES6-y解决方案:
const initial = [{ id: 1, amount: 10, date: '21/01/2017' }, { id: 1, amount: 10, date: '21/01/2017' }, { id: 1, amount: 30, date: '22/01/2017' }, { id: 2, amount: 10, date: '21/01/2017' }];
const parse = obj => obj.reduce((final, { date, id, amount }) => {
let group = final[date] = final[date] || {};
group[id] = group[id] || { amount: 0 };
group[id].amount += amount;
return final;
}, {});
const final = parse(initial);
console.log(final);

您希望添加适当的逻辑来处理丢失/错误的date
,id
或amount
密钥。
答案 2 :(得分:3)
作为图书馆的粉丝Ramda(免责声明:我是其中一位作者),我可能会用它来使一切更明确:
const {pipe, groupBy, prop, map, pluck, sum} = R
const data = [
{"amount": 10, "date": "21/01/2017", "id": 1},
{"amount": 10, "date": "21/01/2017", "id": 1},
{"amount": 30, "date": "22/01/2017", "id": 1},
{"amount": 10, "date": "21/01/2017", "id": 2}
]
const consolidate = pipe(
groupBy(prop('date')),
map(groupBy(prop('id'))),
map(map(pluck('amount'))),
map(map(sum))
)
console.log(consolidate(data))
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>
当然,使用库来解决这个问题简直太过分了,比如来自@NinaSholz的解决方案就好了。但是如果你找到几个可以提供帮助的地方,可能值得研究一下这样的事情。
答案 3 :(得分:0)
你可以通过_.groupBy
:
const res = _.chain(data)
.groupBy('date')
.mapValues(dateObj => _.chain(dateObj)
.groupBy('id')
.mapValues(idObj => ({ amount: _.sumBy(idObj, 'amount') }))
.value()
)
.value();