WEB+DB PRESS vol67が家に届いたのでぼちぼち読んでます。特集の所で「関数的なMapReduceによる問題解決」ということでHaskellを使ってMapとReduceで問題を解いてみようというのがありました。コードはこんな感じでした。
# via WEB+DB PRESS vol67 let ret1 = zip [0..] [10, 20, 30, 40, 50] let mul (i, x) = x * i let ret2 = map mul ret1 foldl (+) 0 ret2
これで結果が400になるという感じですね。ということでさくっとC#でも書いてみました。無限リスト作るのにGenerateメソッドがほしかったのでInteractive ExtensionsをNuGetで参照に追加しています。
namespace CSSample { using System; using System.Linq; class Program { // Interactive Extensions static void Main(string[] args) { var ret = EnumerableEx // 無限リスト .Generate(0, _ => true, i => i + 1, i => i) // Tuple化 .Zip(new[] { 10, 20, 30, 40, 50 }, Tuple.Create) // Map .Select(t => t.Item1 * t.Item2) // Reduce(Sumを使ったほうがいいけど、任意の集計という意味合いも // こめてAggregate使ってみた .Aggregate((i, j) => i + j); // 表示 Console.WriteLine(ret); } } }
いやはや、流石に簡潔さでは負けるとしても同じ概念でC#でも処理をかけるのは素晴らしいですね!因みに、LINQで書いてるので、この処理を並列化させることはとても簡単にできたりします。(こんな軽い処理だと意味無いけど)
var ret = EnumerableEx // 無限リスト .Generate(0, _ => true, i => i + 1, i => i) // Tuple化 .Zip(new[] { 10, 20, 30, 40, 50 }, Tuple.Create) // 並列化 .AsParallel() // Map .Select(t => t.Item1 * t.Item2) // Reduce(Sumを使ったほうがいいけど、任意の集計という意味合いも // こめてAggregate使ってみた .Aggregate((i, j) => i + j);
ここらへんLINQをベースに色んなことが出来るように機能拡張されていってるので、とりあえずLINQで書いておけば色々できるようになる日も近いかもしれない?というWEB+DB PRESSを読んでて思いついた雑感でした。
因みにこのプログラムは下記に置いてます。