この記事は bouzuya's RxJS Advent Calendar 2015 の 12 日目かつ RxJS Advent Calendar 2015 の 12 日目です。
はじめに
今日は ReactiveX の Mathematical and Aggregate Operators について RxJS の API ドキュメントを読んだりサンプルコードを書いたりしていきます。
また RxJS 4.0.7 を対象にしています。
Observable の集約
Observable.prototype.average
- ReactiveX - Average operator
Observable.prototype.averageAPI DocumentObservable.prototype.averageSource Code
平均を流します。
import { Observable } from 'rx';
Observable
.from([1, 3, 5])
.average()
.subscribe(
value => console.log(`onNext: ${value}`),
error => console.log(`onError: ${error}`),
() => console.log('onCompleted')
);
// onNext: 3
// onCompleted
average は引数に selector を取れるのですが、count は引数に predicate を取れるので、何を基準にしているのかよく分からないです。
Observable.prototype.concat
concat は結合のときに書いてしまったので割愛します。
Observable.prototype.count
- ReactiveX - Count operator
Observable.prototype.countAPI DocumentObservable.prototype.countSource Code
import { Observable } from 'rx';
Observable
.from([1, 2, 3, 4, 5])
.count()
.subscribe(
value => console.log(`onNext: ${value}`),
error => console.log(`onError: ${error}`),
() => console.log('onCompleted')
);
// onNext: 5
// onCompleted
前述の通り predicate を取れます。filter してから count すればいいのにと個人的には思ってしまいます。
Observable.prototype.max / Observable.prototype.min
- ReactiveX - Max operator
Observable.prototype.maxAPI DocumentObservable.prototype.maxSource Code- ReactiveX - Min operator
Observable.prototype.minAPI DocumentObservable.prototype.minSource Code
最大値 / 最小値を流します。comparer を引数に取れます。
import { Observable } from 'rx';
Observable
.from([1, 4, 5, 2, 3])
.max()
.subscribe(
value => console.log(`onNext: ${value}`),
error => console.log(`onError: ${error}`),
() => console.log('onCompleted')
);
// onNext: 5
// onCompleted
ソースコードを見ると Observable.prototype.maxBy / minBy を使って実装されていることが分かります。
Observable.prototype.reduce
- ReactiveX - Reduce operator
Observable.prototype.reduceAPI DocumentObservable.prototype.reduceSource Code
Array.prototype.reduce 相当のものです。
import { Observable } from 'rx';
Observable
.from([1, 2, 3, 4, 5])
.reduce((sum, i) => sum + i, 0)
.subscribe(
value => console.log(`onNext: ${value}`),
error => console.log(`onError: ${error}`),
() => console.log('onCompleted')
);
// onNext: 15
// onCompleted
Observable.prototype.scan の際にも書きましたが、reduce よりも scan を使う場面のほうが多いように感じます。
Observable.prototype.sum
合計を返します。
import { Observable } from 'rx';
Observable
.from([1, 2, 3, 4, 5])
.sum()
.subscribe(
value => console.log(`onNext: ${value}`),
error => console.log(`onError: ${error}`),
() => console.log('onCompleted')
);
// onNext: 15
// onCompleted
さきほどの Observable.prototype.reduce で sum っぽいものを書いてしまいました……。実装自体は reduce を使うわけではなく個別に実装されています。
おわりに
ReactiveX の Mathematical and Aggregate Operators を見ました。
難しい動きのものはなさそうですね。