我有一个对象数组,如下所示:
arr = [
{
totalPrice:{
value:5,
currencyId:0
}
},
{
totalPrice:{
value:1,
currencyId:0
}
},
{
totalPrice:{
value:6,
currencyId:0
}
}
]
如果所有的totalPrice对象都具有相同的currencyId,我想做的就是得到一个包含值总和的单个对象(totalPrice)。
第一步是确定所有totalPrice对象是否具有相同的currencyId:
var canBeMerged = arr.every(l => l.totalPrice.currencyId === arr[0].totalPrice.currencyId);
然后:
var merged = null;
if(canBeMerged){
var valueSum = 0;
for (var k=0; k<arr.length; k++) {
valueSum += arr[k].totalPrice.value;
}
merged = {value: valueSum, currencyId: arr[0].totalPrice.currencyId}
}
是否有一种方法可以用一种方法完成所有这些工作?我认为reduce函数可以做到这一点,但我不知道该怎么做。
任何帮助将不胜感激:)
答案 0 :(得分:0)
let merged = {
value: arr.
filter(e => e.totalPrice.currencyId === arr[0].totalPrice.currencyId).
reduce((a, b) => a + b.totalPrice.value, 0),
currencyId: arr[0].totalPrice.currencyId
};
我们首先使用{{1}过滤掉arr
数组的所有条目,其中属性totalPrice.currencyId
与arr
数组中第一个条目的属性不匹配}。 filter
返回一个新的过滤项目数组。我们可以链接filter
来汇总此过滤数组中的值。
答案 1 :(得分:0)
这使用一个对象来累加每个currencyId
的值。
let merge = arr => {
d = {};
arr.forEach(a => d[a.totalPrice.currencyId] = (d[a.totalPrice.currencyId] ? d[a.totalPrice.currencyId] : 0) + a.totalPrice.value);
return Object.entries(d).map(([k, i]) => ({ value: i, currencyId: parseInt(k) }));
}
示例:
>> arr = [
{
totalPrice:{
value:5,
currencyId:0
}
},
{
totalPrice:{
value:1,
currencyId:0
}
},
{
totalPrice:{
value:6,
currencyId:0
}
}
]
>> merge(arr)
[{ value:12, currencyId:0 }]
>> arr = [
{
totalPrice:{
value:5,
currencyId:0
}
},
{
totalPrice:{
value:1,
currencyId:1
}
},
{
totalPrice:{
value:6,
currencyId:0
}
}
]
>> merge(arr)
[{ value:11, currencyId:0 }, { value:1, currencyId:1 }]
答案 2 :(得分:-1)
以下是功能样式的示例:
pipe = (...fns) => obj => fns.reduce((r, f) => r === null ? null : f(r), obj);
ifAll = fn => a => a.every(fn) ? a : null;
pick = prop => a => a.map(x => x[prop]);
sum = a => a.reduce((x, y) => x + y, 0);
//
sumCurr = pipe(
pick('totalPrice'),
ifAll(x => x.currencyId === 0),
pick('value'),
sum,
);
//
arr = [
{
totalPrice:{
value:5,
currencyId:0
}
},
{
totalPrice:{
value:1,
currencyId:0
}
},
{
totalPrice:{
value:6,
currencyId:0
}
}
]
console.log(sumCurr(arr))
尽管我实际上会使用lodash或ramda之类的库,但已经提供了这类内容。
如果目标不支持every
和some
,可以用reduce
轻松表示它们:
every = (a, f) => a.reduce((r, x) => r && f(x), true);
some = (a, f) => a.reduce((r, x) => r || f(x), false);