C# でリストをフィルターして、条件に合致した要素のみを持つリストを生成する方法

C# でリストをフィルターして、条件に合致した要素のみを持つリストを生成する

クラスのオブジェクトが複数入っているリスト (List) があって、条件を指定して、それに合った要素のみを持つ新しいリストを生成したい時ありませんか?

例えば、次のような Student クラスのリスト List<Student> があって、そのうち、Birthday が null の Student オブジェクトのみを含むリストを取得したいような時です。

class Student
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime? Birthday { get; set; }
    public bool TestPassed { get; set; }

    public Student(string firstName, string lastName, DateTime? birthday, bool testPassed)
    {
        FirstName = firstName;
        LastName = lastName;
        Birthday = birthday;
        TestPassed = testPassed;
    }
}

C# でリストをフィルターして、条件に合致した要素のみを持つリストを生成したい時には、ListFindAll メソッドや、LinqWhere メソッドが使えます。

使い方は リスト.FindAll(obj => [obj を使った条件式])リスト.Where(obj => [obj を使った条件式]).ToList()のような感じで指定できます。

どちらも obj としている箇所は他の名前でも大丈夫で、データ型はリストに入っているオブジェクトのデータ型になります。

Linq の Where のほうは IEnumerable を返すので、ToList メソッドで List に変換しています。


C# でリストをフィルターして、条件に合致した要素のみを持つリストを生成するサンプルーコードは次の通りです。

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var students = new List<Student>();
            students.Add(new Student("Kana", "Yamada", null, true));
            students.Add(new Student("Keita", "Maeda", Convert.ToDateTime("2010/05/15"), true));
            students.Add(new Student("Kaede", "Tanaka", Convert.ToDateTime("2009/02/01"), false));
            students.Add(new Student("Ryota", "Suzuki", Convert.ToDateTime("2010/11/24"), true));
            students.Add(new Student("Saki", "Taguchi", null, false));

            var students1 = students.FindAll(s => s.Birthday == null);
            foreach (var s in students1)
            {
                Console.WriteLine(s.FirstName);
            }

            Console.WriteLine("-------------------");

            var students2 = students.Where(s => s.Birthday == null).ToList();
            foreach (var s in students2)
            {
                Console.WriteLine(s.FirstName);
            }

            Console.WriteLine("-------------------");

            var students3 = students.Where(s => s.Birthday == null && s.TestPassed ).ToList();
            foreach(var s in students3)
            {
                Console.WriteLine(s.FirstName);
            }
        }
    }

    class Student
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime? Birthday { get; set; }
        public bool TestPassed { get; set; }

        public Student(string firstName, string lastName, DateTime? birthday, bool testPassed)
        {
            FirstName = firstName;
            LastName = lastName;
            Birthday = birthday;
            TestPassed = testPassed;
        }
    }
}

11 ~ 16 行目は Student クラスのオブジェクトを持つ List を生成しているだけです。

18 行目では、List の FindAll メソッドを使って、students リストの中から、Birthday が null の Student オブジェクトのみを持つ、List<Student> を生成しています。

26 行目では、Linq の Where メソッドを使って、students リストの中から、Birthday が null の Student オブジェクトのみを持つ、List<Student> を生成しています。

複数の条件を指定したい時は if 文などと同様に && や || などで複数の条件を指定することができます。 34 行目では、Birthday が null で TestPassed が true の Student オブジェクトのみを持つ、List<Student> を生成しています。


上のコードを実行すると次のようになります。

Kana
Saki
-------------------
Kana
Saki
-------------------
Kana

C# でリストをフィルターして、条件に合致した要素のみを持つリストを生成する方法 1


新しくできた List の中の Student オブジェクトは、元のリストと同じ Student オブジェクトをポイントしているので、クラス変数の値を変更すると、全てのリストに入っている同じ Student オブジェクトの値が変更されます。

また、フィルターの結果、条件に合致する Student オブジェクトが存在しなくても、空のリストができるだけでエラーにはなりません。


以上、C# でリストをフィルターして、条件に合致した要素のみを持つリストを生成する方法をご紹介しました。

© 2024 C# 入門