该 Scan 操作符对源可观察对象发出的第一个项目应用函数,然后发出该函数的结果作为其自己的第一个发射。它还将函数的结果与源可观察对象发出的第二个项目一起反馈到函数中,以生成其第二个发射。它继续将自己的后续发射与源可观察对象的后续发射一起反馈,以创建其序列的其余部分。
这种类型的操作符在其他上下文中有时被称为“累加器”。
scan
reductions
待定
RxGroovy 将此操作符实现为 scan。例如,以下代码采用一个可观察对象,该对象发出从 1 开始的连续 n 个整数序列,并通过 scan 将其转换为一个发出前 n 个 三角形数 的可观察对象。
1
numbers = Observable.from([1, 2, 3, 4, 5]); numbers.scan({ a, b -> a+b }).subscribe( { println(it); }, // onNext { println("Error: " + it.getMessage()); }, // onError { println("Sequence complete"); } // onCompleted );
1 3 6 10 15 Sequence complete
scan(Func2)
scan 还有一种变体,您可以向其传递一个种子值,以在第一次调用(对于源可观察对象的第一个发射)时传递给累加器函数,以代替缺少的先前调用累加器的结果。请注意,如果您使用此版本,scan 将发出此种子值作为其自己的初始发射。另请注意,传递一个 null 种子与根本不传递种子不同。null 种子是有效的一种种子。
null
scan(R,Func2)
此操作符默认情况下不会在任何特定的 调度器 上运行。
RxJava 将此操作符实现为 scan。
Observable.just(1, 2, 3, 4, 5) .scan(new Func2<Integer, Integer, Integer>() { @Override public Integer call(Integer sum, Integer item) { return sum + item; } }).subscribe(new Subscriber<Integer>() { @Override public void onNext(Integer item) { System.out.println("Next: " + item); } @Override public void onError(Throwable error) { System.err.println("Error: " + error.getMessage()); } @Override public void onCompleted() { System.out.println("Sequence complete."); } });
Next: 1 Next: 3 Next: 6 Next: 10 Next: 15 Sequence complete.
expand scan
RxJS 实现 scan 操作符。
var source = Rx.Observable.range(1, 3) .scan( function (acc, x) { return acc + x; }); var subscription = source.subscribe( function (x) { console.log('Next: ' + x); }, function (err) { console.log('Error: ' + err); }, function () { console.log('Completed'); });
Next: 1 Next: 3 Next: 6 Completed
您可以选择将 scan 传递一个种子值作为附加参数。scan 将在第一次调用(对于源可观察对象的第一个发射)时将此种子值传递给累加器函数,以代替缺少的先前调用累加器的结果。
var source = Rx.Observable.range(1, 3) .scan( function (acc, x) { return acc * x; }, 1 ); var subscription = source.subscribe( function (x) { console.log('Next: ' + x); }, function (err) { console.log('Error: ' + err); }, function () { console.log('Completed'); });
Next: 1 Next: 2 Next: 6 Completed
scan 存在于以下每个发行版中
rx.js
rx.all.js
rx.all.compat.js
rx.compat.js
rx.lite.js
rx.lite.compat.js
RxJS 还实现了 expand 操作符,它有点类似。它不是将函数应用于函数的先前返回值与源可观察对象发出的下一个项目相结合,这样它发出的项目数等于源可观察对象发出的项目数,expand 只是将函数的返回值反馈回函数,而不考虑可观察对象的未来发射,这样它就会以自己的速度继续创建新值。
expand
var source = Rx.Observable.return(42) .expand(function (x) { return Rx.Observable.return(42 + x); }) .take(5); var subscription = source.subscribe( function (x) { console.log('Next: ' + x); }, function (err) { console.log('Error: ' + err); }, function () { console.log('Completed'); });
Next: 42 Next: 84 Next: 126 Next: 168 Next: 210 Completed
expand 存在于以下每个发行版中
rx.experimental.js
expand 需要以下发行版之一
Scan
RxPHP 将此操作符实现为 scan。
对可观察序列应用累加器函数并返回每个中间结果。可选的种子值用作初始累加器值。
//from https://github.com/ReactiveX/RxPHP/blob/master/demo/scan/scan.php //Without a seed $source = Rx\Observable::range(1, 3); $subscription = $source ->scan(function ($acc, $x) { return $acc + $x; }) ->subscribe($createStdoutObserver());
Next value: 1 Next value: 3 Next value: 6 Complete!
//from https://github.com/ReactiveX/RxPHP/blob/master/demo/scan/scan-with-seed.php //With a seed $source = Rx\Observable::range(1, 3); $subscription = $source ->scan(function ($acc, $x) { return $acc * $x; }, 1) ->subscribe($createStdoutObserver());
Next value: 1 Next value: 2 Next value: 6 Complete!