Angular RXJS groupBy Observable<;对象[]>;

Angular RXJS groupBy Observable<;对象[]>;,angular,rxjs,observable,Angular,Rxjs,Observable,我有条目$:可观察: 我想按groupId对它们进行分组。我试着这样做: groupBy(books => books.map(book => book.groupId)), mergeMap(innerObs => innerObs.skip(1).map(books => books.map(book => book.groupTitle))); 然而,它没有起作用。在这种情况下,如何按groupId分组(可观察)只需使用groupBy,然后将它们全部合并

我有
条目$:可观察

我想按groupId对它们进行分组。我试着这样做:

groupBy(books => books.map(book => book.groupId)),
 mergeMap(innerObs => innerObs.skip(1).map(books => books.map(book => book.groupTitle)));

然而,它没有起作用。在这种情况下,如何按groupId分组<代码>(可观察)

只需使用
groupBy
,然后将它们全部合并

$data.pipe(
    groupBy(book => book.groupId),
    mergeMap(group => group.pipe(toArray()))
)
.subscribe(console.log)
高阶可观测 如果您想要更高阶的可观测值,实际上可以使用
groupBy
rxjs操作符

const数据=[
{groupId:“foo”,值:1},
{groupId:“foo”,值:3},
{groupId:“foo”,值:5},
{groupId:“bar”,值:42},
{groupId:“bar”,值:1337},
];
来自(数据)。管道(
groupBy(item=>item.groupId)
)
.subscribe(console.log);
这将产生一个可观察的,每个组发射一个可观察的,并且在每个内部可观察上,相应的项目将被发射

群的可观测性 相反,如果您想要一个只发出组的可观察对象,那么这实际上与rxjs或其
groupBy
操作符无关。相反,这只是一个关于如何在Javascript中对数组进行分组的基本问题

这方面没有内置的方法,但是像lodash这样的库都有这样的函数。您也可以手工操作:

const数据=[
{groupId:“foo”,值:1},
{groupId:“foo”,值:3},
{groupId:“foo”,值:5},
{groupId:“bar”,值:42},
{groupId:“bar”,值:1337},
];
constgroupby=(数据,keyFn)=>data.reduce((agg,item)=>{
常数组=键Fn(项目);
agg[集团]=[…(agg[集团]| |[]),项目];
返回agg;
}, {});
(数据)管道(
映射(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()之前使用
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);
输出将是

{
    "foo": [{ "groupId": "foo", "value": 3 }, { "groupId": "foo", "value": 5 }],
    "bar": [{ "groupId": "bar", "value": 42 }, { "groupId": "bar", "value": 1337 }]
} 

你真的想把它分组成一个更高阶的可观察对象吗?或者你真的想把它转换成一个组列表的可观察对象吗?我想按GroupID分组,并将它们作为数组返回。现在我从可观察对象开始(因为[]groupby没有理解我)也许我只需要将这个可观测值转换为普通数组,然后使用普通groupby。你知道如何将它转换为普通数组吗?你没有回答我的问题。你想要一个更高阶的可观测值吗(一个可观测值,每个组发射一个可观测值)或者是一个发射组的单一观测值?很抱歉,我希望看到这两种变体来学习如何处理数据。如果成本太高,我希望看到高阶观测值的解决方案。谢谢。你找到解决方案了吗?我也很困惑为什么groupBy会给我一个数组,所以我无法进行组。它不适用于ObsRxjs 6.3.2+Angular 6.1.8->@dunaskdunsay说,你得到了一个数组。在下面的代码示例中,typescript给出了一个错误“类型{name:string;age:number;}[]'
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));
感谢您的帮助和时间。不过,对于更高阶的可观察对象:from(data).pipe(groupBy(item=>item.groupId))我以前尝试过这个方法,但它不起作用,因为我有一个可观察的数组,它不仅仅是一个简单的类似对象的对象;它是一个对象[]groupId在item中是未知的,因为在本例中item是一个对象[]的数组,但如果我更进一步:groupBy(books=>books.map(book=>book.groupId))它认为我以数组为键,结果是错误的。我将尝试观察组。非常感谢这个答案,我一直在寻找这个答案,这很有趣:)你能详细说明你的答案吗?
const 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 }]
}