我有一个包含4个字段的数组,并且必须按两个属性进行分组并汇总(求和)分组数组中的一个字段。
尝试按多个分组不起作用。
下面的代码我试图将数组操纵到期望的列表,但是不确定如何使用RxJs达到下面的期望结果
from(this.dummyData)
.pipe(
groupBy(
function (e) {
return { category: e.category, manDate: e.manDate }; //is this valid at all?
},
function (e) { return e; }),
mergeMap(group => zip(of(group.key), group.pipe(toArray())))
)
.subscribe( function(result) {
console.log(result);
});
现有数组:
[{
category : "Printer",
manDate : "02/01/2019",
amount : 90
},
{
category : "Printer",
manDate : "02/01/2019",
amount : 100
},
{
category : "Printer",
manDate : "02/03/2019",
amount : 90
},
{
category : "Printer",
manDate : "02/04/2019",
amount : 90
},
{
category : "Scanner",
manDate : "08/21/2019",
amount : 8
},
{
category : "Scanner",
manDate : "08/21/2019",
amount : 25
},
{
category : "Scanner",
manDate : "08/21/2019",
amount : 20
},
{
category : "Scanner",
manDate : "08/21/2019",
amount : 10
}
];
预期:
[{
category : "Printer",
subCategory : "A",
manDate : "02/01/2019",
amount : 190
},{
category : "Printer",
subCategory : "A",
manDate : "02/03/2019",
amount : 90
},{
category : "Printer",
subCategory : "A",
manDate : "02/04/2019",
amount : 90
},{
category : "Scanner",
subCategory : "A",
manDate : "08/21/2019",
amount : 63
}]
我需要任何人的帮助才能达到这个结果。
答案 0 :(得分:1)
from(dummyData)
.pipe(
groupBy(// Group them by category and return the appropriate Arrays
val => val.category
),
mergeMap(group => {
return group.pipe(toArray());
}),
mergeMap((array) => {// Take each from above array and group each array by manDate
return from(array).pipe(groupBy(
val => val.manDate,
),
mergeMap(group => {
return group.pipe(toArray()); // return the group values as Arrays
})
);
}),
map((val) => { //For each array returned , calculate the sum and map it to the Object you wanted
let amount = 0;
val.map(v => {
amount = amount + v.amount;
});
return {category: val[0].category, manDate: val[0].manDate, amount};
}),
toArray() //finally combine all returned objects to an array
).subscribe(
val => console.log(val)
);
我很难缠住它,但这似乎行得通。如果有帮助,别忘了投票,谢谢!
答案 1 :(得分:1)
尝试此方法,看它是否适合您的需求。您不需要将RXjs分组为IMO。可能还有更多方法可以为所需的输出操作输入数组,但这是我相对快速且易于阅读的解决方案。让我知道它如何适合您的情况:)
transform(array: Array<any>) {
const newArray = [];
array.forEach(item => {
const index = newArray.findIndex(
i => i.category === item.category && i.manDate === item.manDate
);
if (index >= 0) {
newArray[index].amount += item.amount;
} else {
newArray.push(item);
}
});
return newArray;
}
答案 2 :(得分:0)
我认为我们可以在这里使用reduce。
from(dummyData)
.pipe(
groupBy( val => val.category ), // Group them by category and return the appropriate Arrays
mergeMap(group => { return group.pipe(toArray()); }),
mergeMap((array) => {// Take each from above array and group each array by manDate
return from(array).pipe(
groupBy( val => val.manDate, ),
mergeMap(group => {
return group.pipe(toArray()); // return the group values as Arrays
})
);
}),
mergeMap((array) => {// Take each from above array and group each array by manDate
return from(array).pipe(
reduce((acc, curr) => ({
category: curr.category,
manDate: curr.manDate,
amount: curr.amount + acc.amount
}), { category: '', manDate: '', amount: 0})
);
}),
).subscribe(
val => console.log(val));