如何在对象数组上使用 rxjs distinct

how to use rxjs distinct on array of object

关于这个问题,我已经咨询过其他问题,但我没有从洞中拉出蜘蛛。我必须在对象数组上使用 distinct,而我向您建议的代码 distinct 不起作用,而且我在控制台中没有错误。我怎样才能让它发挥作用?

近期用车

export class CarRecent {

    id:number;
    carId:number;
    userId:number;
    imageURL:string;

}

汽车服务

 getRecentCars(userId){

    let params = new HttpParams().set('userId', userId);
    let options = {headers:this.headers, params:params};

    return this.http.get<CarRecent[]>(this.host + 'getRecentCars', options);

  }

recentCar.component.ts

export class RecentCarsComponent implements OnInit {

  url:string = 'assets/';

  recentCars = new BehaviorSubject<CarRecent[]>(null);
  subscriptionRecentCars;

  constructor( public carsService:CarsService, public authService:AuthenticationService ) { }

  ngOnInit(): void {

    this.loadRecentCars();

  }

  loadRecentCars(){

    this.subscriptionRecentCars = this.carsService.getRecentCars(this.authService.currentUserValue.id)
    .pipe( 
      tap( cars => console.log(cars) ),
      distinct( (car:any) => car.carId )
    )  
    .subscribe({
        next:cars => {
          this.recentCars.next(cars);
        }
      })

  }

}

RxJS 运算符经常与数组函数混淆,但它们对整个值进行运算 return 由 observable 编辑 - 它们并不特定于数组。

在您的情况下,您希望 return 基于某个键的不同对象数组。您想要将数组 returned 由 observable 转换为另一个值 - 数组的子集。在管道中转换数据时,使用 map 运算符。

进入 map 运算符后,您可以将数组缩减为 return 个不同的值。

ngOnInit() {

  this.carsService.getRecentCars(this.authService.currentUserValue.id)
    .pipe( 
      tap(cars => console.log(cars)),
      map(cars => {
        const uniques = new Set();
        return cars.reduce((arr, current) => {  
          if (!uniques.has(current.carId)) {
            arr.push(current);
            uniques.add(current.carId);
          }
          return arr;
        }, []);
      })
    ).subscribe({ 
      next:cars => {
        this.recentCars.next(cars);
      }
    });  
}

我使用了 Set 来避免冗余数组迭代。

演示:https://stackblitz.com/edit/angular-8qnsp8