你差不多懂了。
试着在使用groupBy()
之前使用mergeMap()
或concatMap()
。
举个例子:
const people = [
{ name: 'Sue', age: 25 },
{ name: 'Joe', age: 30 },
{ name: 'Frank', age: 25 },
{ name: 'Sarah', age: 35 }
];
of(people) // <- this gets Observable<Object[]>
.pipe(
mergeMap(res => res), // <- use concatMap() if you care about the order
groupBy(person => person.age, p => p.name),
mergeMap(group => zip(of(group.key), group.pipe(toArray())))
)
.subscribe(console.log);
输出:
(2) [25, Array(2)]
(2) [30, Array(1)]
(2) [35, Array(1)]
"TypeError: You provided 'function zipOperatorFunction(source) {"
这才是我在寻找的。 - Marinos An如果你想要一个高阶的 Observable,你其实可以使用 groupBy
rxjs 操作符。
const data = [
{groupId: "foo", value: 1},
{groupId: "foo", value: 3},
{groupId: "foo", value: 5},
{groupId: "bar", value: 42},
{groupId: "bar", value: 1337},
];
from(data).pipe(
groupBy(item => item.groupId)
)
.subscribe(console.log);
这将产生一个可观察对象,它会为每个组发出一个内部可观察对象,对于每个内部可观察对象,相应的项将被发出。
如果你想要一个简单地发出组的可观察对象,那么这实际上与rxjs或其groupBy
运算符无关。相反,这只是一个关于如何在Javascript中分组数组的基本问题。
没有内置的方法可以做到这一点,但像lodash这样的库带有这样的函数。你也可以手动完成:
const data = [
{groupId: "foo", value: 1},
{groupId: "foo", value: 3},
{groupId: "foo", value: 5},
{groupId: "bar", value: 42},
{groupId: "bar", value: 1337},
];
const groupBy = (data, keyFn) => data.reduce((agg, item) => {
const group = keyFn(item);
agg[group] = [...(agg[group] || []), item];
return agg;
}, {});
of(data).pipe(
map(data => groupBy(data, item => item.groupId))
)
.subscribe(console.log);
这将会对整个数据集仅发出一次,但会发出
{
"foo":[
{"groupId":"foo","value":1},
{"groupId":"foo","value":3},
{"groupId":"foo","value":5}
],
"bar":[
{"groupId":"bar","value":42},
{"groupId":"bar","value":1337}
]
}
只需使用 groupBy
操作符,然后将它们全部合并。
$data.pipe(
groupBy(book => book.groupId),
mergeMap(group => group.pipe(toArray()))
)
.subscribe(console.log)
const people = [{ name: 'Sue', age: 25 }, { name: 'Joe', age: 30 }, { name: 'Frank', age: 25 }, { name: 'Sarah', age: 35 }]; const source = of(people); const example = source.pipe(groupBy(p => p.age)); example.subscribe(val => console.log(val));
- Mcanicconst data = [
{ groupId: "foo", value: 1 },
{ groupId: "foo", value: 3 },
{ groupId: "foo", value: 5 },
{ groupId: "bar", value: 42 },
{ groupId: "bar", value: 1337 },
];
of(data).pipe(
mergeMap(res => res),
groupBy(item => item.groupId),
mergeMap(obs => {
return obs.pipe(
toArray(),
map(items => {
return { [obs.key]: items }
})
)
}), toArray()
).subscribe(map((groupResponse) => {
let groups = {};
groupResponse.forEach((item) => { groups = { ...groups, ...item }; });
console.log(groups);
});
输出将会是
{
"foo": [{ "groupId": "foo", "value": 3 }, { "groupId": "foo", "value": 5 }],
"bar": [{ "groupId": "bar", "value": 42 }, { "groupId": "bar", "value": 1337 }]
}