かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

Reactive Extensions入門 13「値を集めて回る」

LINQでお馴染み?Aggregateみたいな動きをするメソッドも当然Reactive Extensionsで使えます!!
ただ、Aggregateは集計し終わった値だけ返しますが、集計途中の値を全て報告してくれるScanというメソッドもあります。


使い方は、どちらも同じで第一引数に初期値、第二引数に集計中の値、戻り値に現在の集計結果を返すというものです。動きの違いを見るにはサンプルプログラムを動かしてみるのが一番です。ということで早速やってみます。

var ob = Observable.Range(1, 20);
            
Console.WriteLine("Scan");
ob.Scan(string.Empty, (s, i) =>
    {
        if (i % 15 == 0) return s + "FizzBuzz";
        if (i % 3 == 0) return s + "Fizz";
        if (i % 5 == 0) return s + "Buzz";
        return s + i.ToString();
    }).Subscribe(Console.WriteLine);

Console.WriteLine("Aggregate");
ob.Aggregate(string.Empty, (s, i) =>
    {
        if (i % 15 == 0) return s + "FizzBuzz";
        if (i % 3 == 0) return s + "Fizz";
        if (i % 5 == 0) return s + "Buzz";
        return s + i.ToString();
    }).Subscribe(Console.WriteLine);

実行結果は以下のようになります。

Scan
1
12
12Fizz
12Fizz4
12Fizz4Buzz
12Fizz4BuzzFizz
12Fizz4BuzzFizz7
12Fizz4BuzzFizz78
12Fizz4BuzzFizz78Fizz
12Fizz4BuzzFizz78FizzBuzz
12Fizz4BuzzFizz78FizzBuzz11
12Fizz4BuzzFizz78FizzBuzz11Fizz
12Fizz4BuzzFizz78FizzBuzz11Fizz13
12Fizz4BuzzFizz78FizzBuzz11Fizz1314
12Fizz4BuzzFizz78FizzBuzz11Fizz1314FizzBuzz
12Fizz4BuzzFizz78FizzBuzz11Fizz1314FizzBuzz16
12Fizz4BuzzFizz78FizzBuzz11Fizz1314FizzBuzz1617
12Fizz4BuzzFizz78FizzBuzz11Fizz1314FizzBuzz1617Fizz
12Fizz4BuzzFizz78FizzBuzz11Fizz1314FizzBuzz1617Fizz19
12Fizz4BuzzFizz78FizzBuzz11Fizz1314FizzBuzz1617Fizz19Buzz
Aggregate
12Fizz4BuzzFizz78FizzBuzz11Fizz1314FizzBuzz1617Fizz19Buzz

Scanが集計中の値をSubscribeしたものに通知してるのに比べてAggregateは集計結果だけSubscribeしたものに通知してるのがわかります。