【C#】LINQのSelectManyでコレクションをスマートに処理する方法

csharp C#

概要

C#のLINQのSelectManyが便利なので、使用方法を記載します。

コレクションをLINQで操作する際に、コレクションの中のコレクションをLINQで一発で回したい時に非常に便利です。

使用例

例えば、全クラスの中から、スコアが50点未満の生徒をピックアップする場合は以下のようになります。

public class Class
{
    public Class(Student[] students)
    {
        this.Students = students;
    }

    public Student[] Students
    {
        get;
        private set;
    }
}

public class Student
{
    public Student(string name, int score)
    {
        this.Name = name;
        this.Score = score;
    }

    public string Name
    {
        get;
        private set;
    }

    public int Score
    {
        get;
        private set;
    }
}

class Program
{
    static void Main(string[] args)
    {
        //テスト用データ生成
        Class classA = new Class(new Student[]
        {
            new Student("Bob", 30),
            new Student("Alice", 90),
        });

        Class classB = new Class(new Student[]
        {
            new Student("Carol", 20),
            new Student("Charlies", 70),
        });

        Class classC = new Class(new Student[]
        {
            new Student("Eve", 45),
        });

        Class[] classes = new Class[] { classA, classB, classC };

        // 全クラスの中から、スコアが50点未満の生徒をピックアップ
        Student[] foundStudents = classes
            .SelectMany(c => c.Students)
            .Where(s => s.Score < 50)
            .ToArray();

        Array.ForEach(foundStudents,
            f => Console.WriteLine("Name = {0}, Score={1}", f.Name, f.Score));

        // Outputs
        // >>> Name = Bob, Score=30
        // >>> Name = Carol, Score = 20
        // >>> Name = Eve, Score = 45
    }
}

上記のように、SelectManyの戻りがIEnumerable<TResult>なのでメソッドチェーンでつなげることができ、コレクション内のコレクションを回せます。

SelectManyを使わないと一部LINQ以外にforeach等使わないといけないので、長めのコードになってしまいます。

コメント