LINQの拡張メソッド一覧と、ほぼ全部のサンプルを作ってみました。

C#LINQメソッドは超便利!!、なんですが…肝心のAPIがわかりづらいです。
そこで、種類ごとにまとめて、簡単なサンプルを書いてみました。

  • 結果の表示に、独自の拡張メソッド ToResult(this IEnumerable) を使用しています。このメソッドは、本文の最後に記載しています。
  • サンプルコードのダウンロードはこちら

要素の取得(単一)

メソッド名 機能
ElementAt
ElementAtOrDefault
指定した位置(インデックス)にある要素を返します。
First
FirstOrDefault
最初の要素を返します。
Last
LastOrDefault
最後の要素を返します。
Single
SingleOrDefault
唯一の要素を返します。該当する要素が複数ある場合、例外をスローします。

該当の要素がない場合は…
 「〜OrDefault」が付いていないメソッドは例外をスローします。
 「〜OrDefault」が付いたメソッドは型の規定値を返します。

var source = new[] { 10, 20, 30, 40 };

Console.WriteLine(source.ElementAt(1));
// -> 20

Console.WriteLine(source.ElementAtOrDefault(5));
// -> 0

Console.WriteLine(source.First());
// -> 10

Console.WriteLine(source.First(e => e > 15));
// -> 20

Console.WriteLine(source.Last());
// -> 40

Console.WriteLine(source.Last(e => e < 35));
// -> 30

try { 
    Console.WriteLine(source.Single());
} catch(Exception e) {
    Console.WriteLine(e);
}
// -> System.InvalidOperationException: Sequence contains more than one element (シーケンスに複数の要素が含まれています)

Console.WriteLine(source.Single(e => e > 35));
// -> 40

要素の取得(複数)

メソッド名 機能
Where 条件を満たす要素をすべて返します。
Distinct 重複を除いたシーケンスを返します。
Skip 先頭から指定された数の要素をスキップし、残りのシーケンスを返します。
SkipWhile 先頭から指定された条件を満たさなくなるまで要素をスキップし、残りのシーケンスを返します。
Take 先頭から指定された数の要素を返します。
TakeWhile 先頭から指定された条件を満たす要素を返します。
var source = new[] { 10, 10, 20, 30, 40 };

Console.WriteLine(source.Where(e => e > 15).ToResult());
// -> {20, 30, 40}

Console.WriteLine(source.Distinct().ToResult());
// -> {10, 20, 30, 40}

Console.WriteLine(source.Skip(3).ToResult());
// -> {30, 40}

Console.WriteLine(source.SkipWhile(e => e < 15).ToResult());
// -> {20, 30, 40}

Console.WriteLine(source.Take(3).ToResult());
// -> {10, 20, 30}

Console.WriteLine(source.TakeWhile(e => e < 15).ToResult());
// -> {10, 10}

集計

メソッド名 機能
Max 最大値を返します。
Min 最小値を返します。
Average 平均値を返します。
Sum 合計を返します。
Count 素数を返します。
Aggregate アキュムレータ関数で処理した結果を返します。
var source = new[] { 10, 20, 30, 40 };

Console.WriteLine(source.Max());
// -> 40

Console.WriteLine(source.Min());
// -> 10

Console.WriteLine(source.Average());
// -> 25

Console.WriteLine(source.Sum());
// -> 100

Console.WriteLine(source.Count());
// -> 4

Console.WriteLine(source.Aggregate((now, next) => now * next));
// -> 24000

// 参考:標本分散
double ave = source.Average();
Console.WriteLine(source.Sum(e => Math.Pow(e - ave, 2)) / source.Count());
// -> 125

判定

メソッド名 機能
All すべての要素が条件を満たしてるか判定します。
Any 条件を満たす要素が含まれているか判定します。
Contains 指定した要素が含まれているかどうかを判定します。
SequenceEqual 2つのシーケンスが等しいかどうかを判定します。
var source = new[] { 10, 20, 30 };

Console.WriteLine(source.All(e => e > 15));
// -> False

Console.WriteLine(source.Any(e => e > 15));
// -> True

Console.WriteLine(source.Contains(20));
// -> True

Console.WriteLine(source.SequenceEqual(new[] { 10, 20, 30 }));
// -> True

集合

メソッド名 機能
Union 指定したシーケンスとの和集合を返します。
Except 指定したシーケンスとの差集合を返します。
Intersect 指定したシーケンスとの積集合を返します。
var first = new[] { 10, 20, 30, 40 };
var second = new[] { 60, 50, 40, 30 };

Console.WriteLine(first.Union(second).ToResult());
// -> {10, 20, 30, 40, 60, 50}

Console.WriteLine(first.Except(second).ToResult());
// -> {10, 20}

Console.WriteLine(first.Intersect(second).ToResult());
// -> {30, 40}

ソート

メソッド名 機能
OrderBy 昇順にソートしたシーケンスを返します。
OrderByDescending 降順にソートしたシーケンスを返します。
ThenBy ソートしたシーケンスに対し、キーが等しい要素同士を昇順にソートしたシーケンスを返します。
ThenByDescending ソートしたシーケンスに対し、キーが等しい要素同士を降順にソートしたシーケンスを返します。
Reverse 逆順にソートしたシーケンスを返します。
var source = new[] {
    new{Name = "A", Value = 20},
    new{Name = "B", Value = 10},
    new{Name = "C", Value = 20},
    new{Name = "D", Value = 30},
};

Console.WriteLine(source.OrderBy(e => e.Value).ToResult());
// -> {{ Name = B, Value = 10 },
//     { Name = A, Value = 20 },
//     { Name = C, Value = 20 }, 
//     { Name = D, Value = 30 }}

Console.WriteLine(source.OrderByDescending(e => e.Value).ToResult());
// -> {{ Name = D, Value = 30 },
//     { Name = A, Value = 20 },
//     { Name = C, Value = 20 },
//     { Name = B, Value = 10 }}

Console.WriteLine(source.OrderBy(e => e.Value)
                        .ThenBy(e => e.Name).ToResult());
// -> {{ Name = B, Value = 10 },
//     { Name = A, Value = 20 },
//     { Name = C, Value = 20 }, 
//     { Name = D, Value = 30 }}

Console.WriteLine(source.OrderBy(e => e.Value)
                        .ThenByDescending(e => e.Name).ToResult());
// -> {{ Name = B, Value = 10 },
//     { Name = C, Value = 20 },
//     { Name = A, Value = 20 }, 
//     { Name = D, Value = 30 }}

Console.WriteLine(source.Reverse().ToResult());
// -> {{ Name = D, Value = 30 },
//     { Name = C, Value = 20 },
//     { Name = B, Value = 10 }, 
//     { Name = A, Value = 20 }}

射影

メソッド名 機能
Select 1つの要素を単一の要素に射影します。
SelectMany 1つの要素から複数の要素に射影します。その結果を1つのシーケンスとして返します。
GroupBy 指定のキーで要素をグループ化します。その "キーとグループ" のシーケンスを返します。
var source = new[] {
    new{ Name = "A", Value = 20 },
    new{ Name = "B", Value = 10 },
    new{ Name = "C", Value = 20 },
    new{ Name = "D", Value = 30 },
};

Console.WriteLine(source.Select(e => e.Name).ToResult());
// -> { A, B, C, D }

Console.WriteLine(source.SelectMany(e => new object[] { e.Name, e.Value }).ToResult());
// -> { A, 20, B, 10, C, 20, D, 30 }

Console.WriteLine(source.GroupBy(e => e.Value).ToResult());
// -> { Key = 20, Element = { { Name = A, Value = 20 }, { Name = C, Value = 20 } },
//      Key = 10, Element = { { Name = B, Value = 10 } },
//      Key = 30, Element = { { Name = D, Value = 30 } } }

結合

メソッド名 機能
Join 内部結合を行ったシーケンスを返します。
GroupJoin 左外部結合を行って指定のキーでグループ化します。その "キーとグループ" のシーケンスを返します。
Concat 2つのシーケンスを連結します。
(Unionは同じ要素を一つにまとめますが、Concatは元の要素をすべて返します。)
DefaultIfEmpty シーケンスを返します。シーケンスが空なら、規定値もしくは任意の要素を返します。
Zip 指定した関数で、2つのシーケンスを1つのシーケンスにマージします。
var outer = new[] {
    new{ Name = "A", Value = 10 },
    new{ Name = "B", Value = 20 },
    new{ Name = "C", Value = 30 },
};

var inner = new[] {
    new{ Name = "X", Value = 20 },
    new{ Name = "Y", Value = 30 },
    new{ Name = "Z", Value = 30 }
};

var empty = new int[0];

Console.WriteLine(outer.Join(
    inner,
    o => o.Value,
    i => i.Value,
    (o, i) => new {
        oName = o.Name,
        oValue = o.Value,
        iName = i.Name,
        iValue = i.Value 
    }
).ToResult());
// -> {{ oName = B, oValue = 20, iName = X, iValue = 20 },
//     { oName = C, oValue = 30, iName = Y, iValue = 30 },
//     { oName = C, oValue = 30, iName = Z, iValue = 30 }}

Console.WriteLine(outer.GroupJoin(
    inner,
    o => o.Value,
    i => i.Value,
    (o, i) => new {
        Name = o.Name,
        Value = o.Value,
        Group = i.Select( i => i.Name ).ToResult() 
    }
).ToResult());
// -> {{ Name = A, Value = 10, Group = {} },
//     { Name = B, Value = 20, Group = { X } },
//     { Name = C, Value = 30, Group = { Y, Z } }}

Console.WriteLine(outer.Concat(inner).ToResult());
// -> {{ Name = A, Value = 10 },
//     { Name = B, Value = 20 },
//     { Name = C, Value = 30 },
//     { Name = X, Value = 20 },
//     { Name = Y, Value = 30 },
//     { Name = Z, Value = 30 }}

Console.WriteLine(empty.DefaultIfEmpty().ToResult());
// -> { 0 }

Console.WriteLine(outer.Zip(inner, (o, i) => o.Name + "&" + i.Name).ToResult());
// -> { A&X, B&Y, C&Z }

変換

メソッド名 機能
OfType 各要素を指定した型に変換します。
キャストできない要素は除外します。
Cast 各要素を指定した型に変換します。
キャストできない要素が含まれていた場合、例外をスローします。
ToArray 配列を作成します。
ToDictionary 連想配列(ディクショナリ)を作成します。
ToList リストを生成します。
ToLookup キーコレクション*1を生成します。
AsEnumerable IEnumerable を返します。*2
var mixed = new object[] { "A", "B", 1, 2 };

var source = new[] {
    new{ Name = "A", Value = 20 },
    new{ Name = "B", Value = 10 },
    new{ Name = "C", Value = 20 },
    new{ Name = "D", Value = 30 },
};

Console.WriteLine(mixed.OfType<string>().ToResult());
// -> { A, B }

try
{
    Console.WriteLine(mixed.Cast<string>().ToResult());
}
catch (Exception e)
{
    Console.WriteLine(e);
}
// -> System.InvalidCastException: 型 'System.Int32' のオブジェクトを型 'System.String' にキャストできません。
// (Unable to cast object of type 'System.Int32' to type 'System.String'.)

Console.WriteLine(source.ToArray().ToResult());
// -> {{ Name = A, Value = 20 },
//     { Name = B, Value = 10 },
//     { Name = C, Value = 20 },
//     { Name = D, Value = 30 }}

Console.WriteLine(source.ToDictionary(x => x.Name, x => x.Value).ToResult());
// -> { [A, 20], [B, 10], [C, 20], [D, 30] }

Console.WriteLine(source.ToLookup(x => x.Value, x => x.Name).ToResult());
// -> { Key = 20, Element = { A, C },
//      Key = 10, Element = { B },
//      Key = 30, Element = { D } }

補足 - 結果表示用の拡張メソッド

static String ToResult<TSource>(this IEnumerable<TSource> source)
{
    return "{" + string.Join(", ", source) + "}";
}

static String ToResult<TKey, TSource>(this IEnumerable<IGrouping<TKey, TSource>> source)
{
    return source.Select(group => string.Format("Key={0}, Source={1}", group.Key, group.ToResult())).ToResult();
}

*1:1対多のディクショナリ。例えば、〜.ToLookup()["hoge"] と実行すると、"hoge" に紐付く要素の集合(IEnumerable)が返ってきます。

*2:IEnumerable と同じ名前のメソッドがクラス内に定義されている場合に使います。そのままだと、クラス内のメソッドが優先的に選択されて、IEnumerable の拡張メソッドが呼びだせないためです。