RxJS技术问询:如何使用groupBy操作符实现按动物类型分组并构建指定键值对格式的Observable数组?
用RxJS的groupBy实现分组、键值转换与排序
当然可以用groupBy操作符实现你的需求!虽然很多示例里分组后返回的是数组形式的结果,但我们可以通过串联其他操作符,把每组的数据转换为你想要的键值对结构,再完成排序和合并。
完整实现代码
import { from } from 'rxjs'; import { groupBy, mergeMap, reduce, toArray, map } from 'rxjs/operators'; const animals$ = from([ { animal: 'rat', color: 'grey', speed: 2 }, { animal: 'rat', color: 'black', speed: 3 }, { animal: 'dog', color: 'grey', speed: 2 }, { animal: 'dog', color: 'black', speed: 1 }, { animal: 'cat', color: 'grey', speed: 5 }, { animal: 'cat', color: 'black', speed: 1 }, ]); const result$ = animals$.pipe( // 按animal字段分组,每个分组是一个独立的Observable groupBy(item => item.animal), // 处理每个分组,将组内条目合并为键值对结构 mergeMap(group => group.pipe( reduce((accumulator, currentItem) => { // 把color作为键,speed作为对应值添加到累积对象中 accumulator[currentItem.color] = currentItem.speed; return accumulator; }, { animal: group.key }) // 初始值:包含当前分组的动物名称 ) ), // 将所有处理后的单个对象收集为数组 toArray(), // 按动物名称的字母顺序排序 map(arr => arr.sort((a, b) => a.animal.localeCompare(b.animal))) ); // 订阅输出结果 result$.subscribe(console.log);
代码拆解说明
groupBy(item => item.animal):把原始数据流按animal字段拆分,每个分组对应一个动物类型,分组的key就是动物名称,每个分组本身是一个Observable,包含该动物的所有原始条目。mergeMap+reduce:遍历每个分组Observable,用reduce对组内数据进行累积:初始对象仅包含animal字段(值为分组的key),然后逐个将条目的color作为新键、speed作为对应值添加到对象中,最终每个分组会生成一个符合你需求的键值对对象。toArray():把所有处理好的单个动物对象收集成一个完整的数组Observable。map+sort:用localeCompare对数组按动物名称的字母顺序排序,确保输出结果的顺序符合要求。
输出结果
运行代码后,你会得到完全符合预期的输出:
[ { animal: 'cat', grey: 5, black: 1 }, { animal: 'dog', grey: 2, black: 1 }, { animal: 'rat', grey: 2, black: 3 } ]
内容的提问来源于stack exchange,提问作者пaean
相关产品推荐
相关产品推荐

