RxJS合并对象数组:按name去重并保留tsUpdate最大值
解决RxJS流合并去重并保留tsUpdate最大值项的问题
我来帮你搞定这个需求!要实现把两个RxJS流合并,按name字段去重且保留每个name对应tsUpdate最大的对象,咱们可以分几步来实现:
核心思路
- 先合并两个流的数组数据,得到一个包含所有对象的大数组
- 遍历这个大数组,以
name为分组依据,只保留每组中tsUpdate值最大的对象 - 最后把分组后的结果转回数组格式
完整代码实现
import { of, forkJoin } from 'rxjs'; import { map } from 'rxjs/operators'; const site = of([ { name: 'Joe', age: 30, tsUpdate: 5 }, { name: 'Frank', age: 20, tsUpdate: 4 }, { name: 'Ryan', age: 50, tsUpdate: 4 } ]); const db = of([ { name: 'Jonas', age: 30, tsUpdate: 4 }, { name: 'Frank', age: 21, tsUpdate: 8 }, { name: 'Calgor', age: 50, tsUpdate: 4 }, { name: 'Joe', age: 30, tsUpdate: 4 }, ]); forkJoin([site, db]).pipe( // 第一步:合并两个流的数组为一个大数组 map(([siteData, dbData]) => [...siteData, ...dbData]), // 第二步:按name分组,保留tsUpdate最大的项 map(combinedArray => { return combinedArray.reduce((acc, currentItem) => { // 检查当前name是否已经在分组对象中 const existingItem = acc[currentItem.name]; // 如果没有存在,或者当前项的tsUpdate更大,就替换 if (!existingItem || currentItem.tsUpdate > existingItem.tsUpdate) { acc[currentItem.name] = currentItem; } return acc; }, {} as { [key: string]: typeof combinedArray[0] }); }), // 第三步:把分组对象转成最终的数组格式 map(groupedItems => Object.values(groupedItems)) ).subscribe(finalResult => { console.log('最终结果:', finalResult); });
代码解释
forkJoin([site, db]):等待两个流都完成并发出各自的数组,然后把两个数组作为一个数组返回- 第一个
map操作:使用扩展运算符把两个数组合并成一个包含所有对象的大数组,方便后续统一处理 reduce方法:这是核心逻辑,我们用一个对象来存储每个name对应的最大tsUpdate项。遍历每个对象时,对比当前对象和已存储对象的tsUpdate,保留更大的那个- 最后一个
map操作:把分组用的对象的所有值提取出来,转成我们需要的数组格式
运行这段代码后,你会得到符合预期的结果:每个name只出现一次,且对应的是tsUpdate最大的那个对象。
内容的提问来源于stack exchange,提问作者user3887366
相关产品推荐
相关产品推荐

