C#のLINQを15年ぶりに再学習をしてます
ここ4年ぐらいElixirを使っているため、Elixirと比較して学習してみます
今回の比較お題です
| Elixir | C# |
|---|---|
| Enum.filter | Where |
| Enum.reject | Whereの条件を反転して代用 |
| Enum.group_by | GroupBy |
Enum.filter
お題:2で割り切れる物を取得する
Elixir
iex> Enum.filter([1, 2, 3], fn x -> rem(x, 2) == 0 end)
[2]
C#
List<int> v = [1,2,3];
var ret = v.Where(x => x % 2 == 0);
Console.WriteLine(String.Join(", ", ret));
// 実行結果
2
お題:aを含む物を取得する
Elixir
iex> Enum.filter(["apple", "pear", "banana"], fn fruit -> String.contains?(fruit, "a") end)
["apple", "pear", "banana"]
C#
List<string> v = ["apple", "pear", "banana"];
var ret = v.Where(x => x.Contains("a"));
Console.WriteLine(String.Join(", ", ret));
// 実行結果
apple, pear, banana
お題:22より小さい物を取得する
Elixir
iex> Enum.filter([4, 21, 24, 50], fn seconds -> seconds < 22 end)
[4, 21]
C#
List<int> v = [4, 21, 24, 50];
var ret = v.Where(x => x < 22);
Console.WriteLine(String.Join(", ", ret));
// 実行結果
4, 21
Enum.reject
C#は該当するものがなかったのでWhereの条件を反転する
お題:2で割り切れる物は除外する
Elixir
iex> Enum.reject([1, 2, 3], fn x -> rem(x, 2) == 0 end)
[1, 3]
C#
List<int> v = [1, 2, 3];
var ret = v.Where(x => x % 2 != 0);
Console.WriteLine(String.Join(", ", ret));
// 実行結果
1, 3
Enum.group_by
お題:文字数でグループ化をする
iex> Enum.group_by(~w{ant buffalo cat dingo}, &String.length/1)
%{3 => ["ant", "cat"], 5 => ["dingo"], 7 => ["buffalo"]}
C#
var ret = "ant buffalo cat dingo"
.Split(' ')
.GroupBy(x => x.Length);
foreach (var kvp in ret)
{
Console.Write($"{kvp.Key}:");
Console.WriteLine(String.Join(", ", kvp));
}
// 実行結果
3:ant, cat
7:buffalo
5:dingo
お題:文字数でグループ化をして、先頭の文字を表示する
iex> Enum.group_by(~w{ant buffalo cat dingo}, &String.length/1, &String.first/1)
%{3 => ["a", "c"], 5 => ["d"], 7 => ["b"]}
C#
var ret = "ant buffalo cat dingo"
.Split(' ')
//.Where(x => x.Length > 0) //必要に応じてあった方が良いかも、0文字の時に落ちます
.GroupBy(x => x.Length, x => x[0]);
foreach (var kvp in ret)
{
Console.Write($"{kvp.Key}:");
Console.WriteLine(String.Join(", ", kvp));
}
// 実行結果
3:a, c
7:b
5:d
感想
- 並び順は言語ごと挙動の差はある
- ソートが必要
- C#にもIO.inspectが欲しい
- Elixirは関数の途中(パイプの途中)がデバッグしやすいので同じ機能がC#でも欲しい