将combineLatest中的值映射到Array

时间:2018-02-10 19:08:23

标签: javascript typescript ecmascript-6 rxjs

有这个:

 Observable.combineLatest(localArray.map((i) => {
  return <Observable that returns $value> }))
  .map((statuses) => {
    return statuses.filter((status) => {
      return status.$value === CONDITION
    });
  }).subscribe((eligible: any[]) => {
...

是否可以将订阅中的结果映射回localArray?我想知道哪个eligible项属于哪个localArray条目......

感谢您的帮助。

我在某处读到订单是combineLatest保存的。但是,使用forEach直接映射到索引将不起作用,因为eligible结果可能会返回与localArray不同的长度(如果满足条件)。 < / p>

我可以随时删除.map()并在subscribe块中进行过滤,这样我就可以循环localArray并使用eligible数据进行更新直接如此:localArray.forEach((ai, i) => { ai.eligible = eligible[i] })例如......

2 个答案:

答案 0 :(得分:1)

很难用你提供的少量信息来判断这是否是一个好主意,但它对我来说肯定不是这样。我这样说的原因是因为映射回localArray会在数据流中创建一个隐式循环。也许这正是你所需要的,所以这取决于你。

在这种情况下你可以做的只是发出index(或其他一些标识符),帮助你从localArray映射回combineLatest

像这样。

Observable.combineLatest(localArray.map((i) => {
  return <Observable that returns $value> }))
  .map((statuses) => {
    return [i, statuses.filter((status) => {
      return status.$value === CONDITION
    })];
  }).subscribe((eligible: [number, any[]]) => {
    // eligible now is a tuple type where the left element is the index of the localArray
  });

答案 1 :(得分:1)

首先,代码:

Observable
    // Turn an array, promise, or iterable into an observable.
    .from(localArray)
    // Map values to inner observable, subscribe and emit in order.
    .concatMap((arrayElement: any) => {
        // Returning an observable that returns a value
        return Observable.of(arrayElement);
    })
    // Emit only values that meet the provided condition.
    .filter((value: any) => {
        return value === 'Some condition';
    })
    // Reduces the values from source observable to a single value that's emitted when the source completes.
    // If you need the current accumulated value on each emission, try scan - https://www.learnrxjs.io/operators/transformation/scan.html
    // The second argument here is the seed, the initial value provided the first time reduce is called. (In this case, an empty array)
    .reduce((filteredValue: any, accumulatedFilteredValues: any[]) =>{
        accumulatedFilteredValues.push(filteredValue);
        return accumulatedFilteredValues;
    }, [])
    .subscribe((filteredValueArray: any[]) => {
        // Do something with the array of ordered, filtered values
    });

首先,我创建了一个observable,使用fromlocalArray中发出每个arrayElement。

当发出每个arrayElement时,我将arrayElement映射到将返回一些value的Observable(在这种情况下,我只返回arrayElement)。我使用concatMap因为它会订阅内部observable并在完成后发出它们的值,按照它们的发射顺序

我使用filter仅发出满足条件的value。过滤器使用返回truefalse的函数。如果返回true,则会发出value

最后,我使用reduce收集filteredValue并将其添加到accumulatedFilteredValues数组中。 Reduce将函数作为其第一个参数,将可选种子作为其第二个参数。

传递给reduce的函数接收最新发射(filteredValue)作为其第一个参数,累积值作为第二个参数(空数组[])

将这些运算符应用于发出的值后,传递给subscribe的函数会收到一个包含localArray中已过滤的有序项的数组。

learn-rxjs是一个优秀的RxJS资源,包含各种运算符的示例和描述。

如果您使用的是RxJS&gt; = 5.5,请考虑改用pipeable operators。在这种情况下,代码看起来会更接近这一点:

from(localArray).pipe(
        concatMap((arrayElement: any) => {
            return Observable.of(arrayElement);
        }),
        filter(value => {
            return value === 'Some condition';
        }),
        reduce((filteredValue: any, accumulatedFilteredValues: any[]) => {
            accumulatedFilteredValues.push(filteredValue);
            return accumulatedFilteredValues;
        }, [])
    )
    .subscribe((filteredValueArray: any[]) => {
        // Do something with the array of ordered, filtered values
    });