2016-08-16 4 views
0

観測可能な配列の要素を変換して集約する必要があります。シーケンスは開いており、完了することは決してありません(ネットワークベース)。.scan()は未完成の配列でもっとも最近発行された配列のみを集める

私は現在、次のコードを使用しています:

const numbers = [1,2,3]; 
const numbers$ = new Rx.Subject(); 

const output = numbers$ 
    .flatMap(n => n) 
    .map(n => n*n) 
    .scan((acc, x) => acc.concat([x]), []) 
    .subscribe(n => { console.log(n); }); 

numbers$.next(numbers); 

setTimeout(() => { 
    numbers$.next([5,6,7]) 
}, 1000); 

現在、複数のアレイが放出され、最後に放出された値が現在[1, 4, 9, 25, 36, 49]です。しかし、私はそれらの値が同じ入力配列の中での二乗になりたいだけです。

I.e.正確に2つの配列、すなわち[1,4,9][25, 36, 49]を出力するには、観測可能な出力が必要です。

これを行う方法?

答えて

1

これは、あなたが探しているものでなければなりません:

const output = numbers$ 
    .map((a) => a.map(n => n * n)) 
    .subscribe(n => { console.log(n); }); 

編集:あなたがArray.mapを使用したくない場合は、代わりに、RxJSを使用することができます。

Array.mapを観測値に置き換えて値を2乗し、配列に戻すことができます。これは、(あなたのコメントどおり)distinctまたは他のRxJS演算子を含むように拡張することができます

const output = numbers$ 
    .mergeMap(
     (a) => Rx.Observable.from(a) 
      .map((n) => n * n) 
      .reduce((acc, n) => { acc.push(n); return acc; }, []) 
    ) 
    .subscribe(n => { console.log(n); }); 

あなたは解決策が掲載ソリューション:

const output = numbers$ 
    .flatMap(n => n) 
    .map(n => n*n) 
    .buffer(numbers$.delay(1)) 
    .subscribe(n => { console.log(n); }); 

がベースのタイミングと配列がある唯一の理由れます第1のnextコールと第2のコールとの間の間隔が1ミリ秒を超えるためです。これは何が必要であるように

+0

私はArray.prototype.map()関数を使用して好きではなくRxJSに固執しないでください。私。 '.distinct()'のようなより複雑な変換も行うことができます – Dyna

+1

mergeMap/flatMapをネストされた.from()で使用するソリューションが正しい方法です。また、最後に.reduce()/。scan()の代わりに '.toArray()'を使用して、値を配列にパックし直します。 – Dyna

1

が見える:jsbin

const numbers = [1,2,3]; 
const numbers$ = new Rx.Subject(); 

const output = numbers$ 
    .map(numbers => numbers.map(n => n * n)) 
    .scan((acc, x) => acc.concat([x]), []) 
    .subscribe(n => { console.log(n); }); 

numbers$.next(numbers); 

setTimeout(() => { 
    numbers$.next([5,6,7]) 
}, 1000); 
関連する問題