首页 > 解决方案 > 使用内部订阅将数组映射到另一个数组

问题描述

我有一个 Objects 数组,我们会说它是 off type Objects[]

我需要将每个对象映射到另一种类型的对象,例如,DestinationObject[]但是DestinationObject[]我需要在 Firebase 中查找一个属性,因此我需要进行订阅或pipe(map()).

不幸的是,如果我订阅,我会得到一个订阅,如果我这样做,pipe(map())我会得到一个 Observables 列表,而不是 Observable 对象列表(即我想要Observable<Object[]>而不是Observable<Object>[]

这是代码:

  processUsers(users: Users[], groupUsers: Users[]): Observable<MappedUser[]> {
    return groupUsers.map(groupUser => {
      return this.firebaseService.SubscribableFunction(groupUser.id).pipe(map(array => {
        return {
          name: groupUser.name,
          arrayLength: array.length,
        } as MappedUser;
      }));
    });
  }

所以两个简单的数组对象,我们确实返回了一个 MappedUser,但是由于 SubscribableFunction 上的 pipe(map()),它返回一个 Observable,因此第一行的映射返回一个 Observable 列表。这不是我想要的。

你有什么解决办法?我已经尝试过 map、mergeMap、from() of(),但它似乎没有按预期工作。

更新这里是请求的可订阅函数:

  SubscribableFunction(userId: string): Observable<Equipment[]> {
    const collection = this.afs.collection<Equipment>('equipment', ref => ref.where('userId', '==', userId));
    return collection.snapshotChanges().pipe(map(items => {
      return items.map(item => {
        return {
          id: item.payload.doc.id,
          ...item.payload.doc.data(),
        } as Equipment;
      });
    }));
  }

标签: angularrxjs

解决方案


您快到了。一旦你将源数组映射到一个 observables 数组,你会以类似[obs1, obs2, obs3, ...]. 所以在这里你可以使用 RxJSforkJoin函数来并行触发所有的 observables 并以对象数组的形式获取结果。

尝试以下

processUsers(users: Users[], groupUsers: Users[]): Observable<MappedUser[]> {
  return forkJoin(groupUsers.map(groupUser => { // <-- return `forkJoin` here
    return this.firebaseService.SubscribableFunction(groupUser.id).pipe(map(array => {
      return {
        name: groupUser.name,
        arrayLength: array.length,
      } as MappedUser;
    }));
  }));
}

现在您可以订阅该功能

processUsers(...).subscribe(
  res => console.log(res), // would log `[{MappedUser}, {MappedUser}, {MappedUser},... ],
  err => // good practice to handle HTTP errors
);

注意:RxJSforkJoin只会在所有输入 observables 完成时才会发出。如果您希望从 observables 中获得数据流,您可以查看zipor combineLatest你可以在这里找到它们之间的区别。


推荐阅读