我有一大堆物品,其中有一个"状态"可能具有六种状态之一的字段。使用rxjs库,我试图.groupBy然后.reduce返回六个状态的数组和具有这些状态的项目数。
以下是我服务中的方法:
getStatusTotals() {
return Observable.from(sampleData)
.map(res => res.d.results)
.concatMap(data => data)
.groupBy(item => item.Status)
.mergeMap(group => group
.reduce((total, item) => total, 0)
.map(total => ({ Status: group.key, Count: total }))
)
.toArray()
}
在我调用此服务函数的组件中,我将值设置为statusData,信息显示如下:
<div *ngFor="let t of tracdata | async" class="row">Status: {{t.Status}}; Count: {{t.Count}}</div>
然而,这在我的应用程序中给了我以下内容:
Status: 5 - Dormant; Count: 0
Status: 2 - Active; Count: 0
Status: 4 - Assigned to Section; Count: 0
Status: 1 - Pending Review; Count: 0
Status: 3 - Officer Review; Count: 0
所以我做错了。我试过.count和.forEach,并阅读了rxjs文档,但我一定做错了。请帮忙!
答案 0 :(得分:2)
实际计算状态
时,您的减少量缺少+1.reduce((total, item) => total + 1, 0)
无论如何,你可以用.count()
替换.reduce(..)答案 1 :(得分:1)
正如@ZahiC所说,&input->r
将起作用。
但reduce
只会在您获得所有数据后才会发出。
如果您想在每次reduce
时计算所有内容,则应使用next
代替。
以下是一个例子:
scan
一个正在使用的Plunkr:https://plnkr.co/edit/U2mZC5QpL12NpuHTJOFq?p=preview
编辑:
由于这个函数给出了const { Observable } = Rx;
const sampleData = [
{ status: 'status1' },
{ status: 'status2' },
{ status: 'status1' },
{ status: 'status3' },
{ status: 'status4' },
{ status: 'status2' },
{ status: 'status5' },
{ status: 'status6' },
{ status: 'status4' }
];
Observable
.from(sampleData)
.scan((acc, curr) => {
const status = curr.status;
const count = acc[status] ? acc[status].count : 0;
return Object.assign(acc, {
[status]: { status, count: count + 1 }
});
}, {})
.do(console.log)
.subscribe();
并且你想要一个数组,我为它添加了一个小函数:
object
然后我在const objToArray = (obj) => {
const keys = Object.keys(obj);
return keys.reduce((acc, curr) => [...acc, obj[curr]], []);
}
之前map
Observable
之前:
do
输出如下:
(注意我们有中间结果!)