我试图弄清楚如何从对象列表开始获取分组和聚合的值数组(我可以将其与 ngFor 一起使用),但在我的一生中,我无法让它工作。 数据(这是我的状态的一部分)看起来像这样:
[{name: "A", value: 1, desc: 'something irrelevant'},
{name: "A", value: 3, desc: 'also other properties'},
{name: "B", value: 2, desc: 'etc.'},
{name: "B", value: 5, desc: 'etc.'}]
我想要得到的结果是这样的(注意类型不同):
[{name: "A", value: 4}, {name: "B", value: 7}]
所以,基本上我想找到具有该名称的所有对象的不同“名称”和“值”总和,以及 ngFor | 可以使用的输出。异步。
目前,我几乎可以工作的获取不同值的解决方案是:
this.aggregates:Observable<any[]> = this.store
.select(state => state.valuesList)
.map(valuesList => valuesList.sort((a,b) => {return (a.name > b.name) ? 1 : ((b.name > a.name) ? -1 : 0);} }))
.flatMap(valuesList => valuesList)
.map(value => value.name)
.distinct();
我很乐意从这个开始;问题是,如果我不添加 toArray(),Typescript 会提示“类型字符串不可分配给类型任何[]”;如果我在distinct()之后添加toArray(),它不再提示,但subscribe()不会产生任何结果。
我做错了什么?我应该将所有内容移至 reducer (但我不知道是否可以更改同一 reducer 中不同操作返回的对象类型)? 非常感谢任何帮助。
更新: 我会更高兴有一个工作 groupBy() 实现,因为它应该正是它的用例。
最佳答案
您可以使用groupBy
来做你想做的事,但你必须对从列表派生的可观察对象使用groupBy
运算符 - 因为groupBy
需要一个可观察的项目。
在以下代码片段中,slice
相当于 this.store.select(state => state.valuesList)
const slice = Rx.Observable.of([
{ name: "A", value: 1, desc: "something irrelevant" },
{ name: "A", value: 3, desc: "also other properties" },
{ name: "B", value: 2, desc: "etc." },
{ name: "B", value: 5, desc: "etc." }
]);
const grouped = slice.concatMap(list => Rx.Observable
.from(list)
.groupBy(item => item.name)
.mergeMap(group => group
.reduce((total, item) => total + item.value, 0)
.map(total => ({ name: group.key, value: total }))
)
.toArray()
);
grouped.subscribe(value => console.log(value));
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://unpkg.com/rxjs@5/bundles/Rx.min.js"></script>
关于Angular/ngrx - 对状态值进行分组和聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44087292/