おまけ
ついでに、良く使う範囲での Scala と C# のリスト操作対応表。
Scala | C# |
---|---|
map | Select |
flatMap | SelectMany |
filter | Where |
foldLeft | Aggregate *1 |
foldRight | なし |
reduceLeft | Aggregate *2 |
reduceRight | なし |
foreach | なし |
zip | Zip *3 |
すぐに思いつくのは、この辺りぐらい。Skip とか Take、TakeWhile あたりもあったはず。あとは Single とか First とかかな。
collect が無いのはわりと不便に感じることが多い。C# には PartialFunction が無いのでしょうがないのだろうけど。あと、partition も無い気がする。これは作ってもいいんじゃないかなぁ?と思う。遅延リストにするのは難しいのかもだけど。
そうそう、遅延リスト。これについては C# の方が数段便利だと感じてる。遅延リスト・・・というか、IEnumerable を実装するのがものすごい簡単。基本はメソッドから値を返すときに yield return すれば、あとはよしなにやってくれるので、実装の手間がものすごい少ないです。しかも、遅延リストになる。
たとえば、Select だけれども、自分で実装するなら以下のようなコードでよい。
public static class EnumerableExtensions { public static IEnumerable<U> Select<T, U>(this IEnumerable<T> src, Func<T, U> func) { foreach (var value in src) yield return func(value); } }
これだけで、yield return の各戻り値を要素として取り出せる IEnumerable のインスタンスを返すことが出来る。
ちなみに、yield return は繰り返し構文の中でなくとも使える。例えば、以下だと 1, 2, 3 を要素とする IEnumerable が得られる。
public IEnumerable<int> GetValues() { yield return 1; yield return 2; yield return 3; }
戻り値は IEnumerable でなくても IEnumerator でもOKだったような気もする。ちなみにどちらであっても、次の要素が必要となったときに、メソッドの実行が続行されるようです。なので、無限リストを作成するのも簡単にできると思います。
public IEnumerable<int> Start(int start) { for(var i=start;; i++) yield return i; }
Scala の場合、Stream をつかって、ほげほげしないといけないので、ちょっと面倒です。
追記
id:bleis-tift さんの指摘をうけて、対応表の Zip 他に注釈を追加しました。