かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

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したものに通知してるのがわかります。