Angular 14中如何对Observable对象数组按厂商分组?
Angular 14 对象数组按厂商分组解决方案
方法一:RxJS groupBy 正确用法
你的问题根源在于 cars$ 是返回整个数组的 Observable,直接用 groupBy 会把整个数组当作单个元素处理。需要先将数组拆分为单个对象的流,再进行分组:
import { groupBy, mergeMap, toArray } from 'rxjs/operators'; // 定义Car类型(可选,增强类型提示) interface Car { id: number; manufacturer: string; model: string; } this.cars$.pipe( // 将数组展开为单个Car对象的Observable流 mergeMap((cars: Car[]) => cars), // 按manufacturer字段分组 groupBy(car => car.manufacturer), // 将每个分组转换为数组 mergeMap(group => group.pipe(toArray())) ).subscribe(groups => { // groups是分组后的数组集合,格式为 [[Ford车型数组], [Toyota车型数组]] groups.forEach(group => { console.log(`厂商:${group[0].manufacturer}`, group); }); });
方法二:JavaScript reduce 函数实现分组
如果更倾向于在数组层面处理,可以用 reduce 直接对Observable返回的数组进行分组,逻辑更直观:
import { map } from 'rxjs/operators'; this.cars$.pipe( map((cars: Car[]) => { return cars.reduce((groupedObj, car) => { // 取出当前厂商对应的分组,不存在则创建空数组 const currentGroup = groupedObj[car.manufacturer] || []; // 将当前车型加入分组 currentGroup.push(car); // 更新分组对象 groupedObj[car.manufacturer] = currentGroup; return groupedObj; }, {} as Record<string, Car[]>); // 初始值为空对象,指定类型增强提示 }) ).subscribe(groupedResult => { // groupedResult是键为厂商名、值为对应车型数组的对象 console.log('Ford车型列表:', groupedResult.ford); console.log('Toyota车型列表:', groupedResult.Toyota); });
reduce 逻辑说明
groupedObj是累加器,从空对象开始逐步构建分组结果- 遍历每个车型时,检查当前厂商是否已存在分组,不存在则初始化空数组
- 将当前车型推入对应分组,再更新累加器
- 最终返回的
groupedObj就是按厂商分组的完整结果
内容的提问来源于stack exchange,提问作者Scottish Smile
相关产品推荐
相关产品推荐

