C#のListから生徒を検索しよう!foreach・Find・FindAllを初心者向けに解説
前回の記事「C#のListから要素を削除しよう!Remove・RemoveAt・Clearを初心者向けに解説」では、Listから生徒を削除する方法を確認しました。
生徒を追加・削除できるようになると、次は「登録した生徒の中から、目的の人を探したい」という場面が出てきます。
人数が3人なら目で探せますが、30人、100人と増えると大変です。そこで今回は、Listから条件に合う生徒を検索してみましょう。
最初はforeach文とif文を組み合わせ、検索の仕組みを確認します。その後、FindとFindAllを使って、同じ処理を短く書き換えます。
Listを検索する3つの方法
この記事で扱う3つの方法には、次の違いがあります。

foreach + ifで仕組みを確認し、Findで最初の1件、FindAllで条件に合う全員を取得します。foreach + if:1人ずつ取り出して条件を確認するFind:条件に合う最初の1件を取得するFindAll:条件に合うすべての要素を新しいListで取得する
まずは処理の流れが見えやすいforeach + ifから始めます。
今回使うStudentリスト
今回は、4人の生徒をListに入れておきます。
List<Student> students = new List<Student>();
students.Add(new Student { Name = "田中", Score = 75 });
students.Add(new Student { Name = "佐藤", Score = 82 });
students.Add(new Student { Name = "鈴木", Score = 88 });
students.Add(new Student { Name = "高橋", Score = 65 });
このListから、名前が「鈴木」の生徒や、点数が80点以上の生徒を探します。
foreach文とif文で名前を検索する
foreach文で生徒を1人ずつ取り出し、if文で名前を確認します。
foreach (var student in students)
{
if (student.Name == "鈴木")
{
Console.WriteLine($"{student.Name}さんを見つけました。");
student.ShowScore();
}
}
student.Name == "鈴木"は、「今取り出した生徒の名前が鈴木と同じか」を確認しています。
田中さんと佐藤さんでは条件がfalseになります。鈴木さんを取り出したときだけ条件がtrueになり、メッセージと点数が表示されます。
見つけたらbreakで検索を終える
探している生徒が1人だけなら、見つけた後に残りの生徒を確認する必要はありません。breakを使うと、foreach文を途中で終了できます。
foreach (var student in students)
{
if (student.Name == "鈴木")
{
student.ShowScore();
break;
}
}
breakが実行されると、それ以降の高橋さんは確認せずに繰り返しを終えます。
見つからなかった場合も表示する
検索結果が見つかったかどうかを覚えておくには、bool変数を使います。
bool found = false;
foreach (var student in students)
{
if (student.Name == "鈴木")
{
student.ShowScore();
found = true;
break;
}
}
if (found == false)
{
Console.WriteLine("生徒が見つかりませんでした。");
}
最初はfalseにしておき、見つかったときにtrueへ変更します。最後までfalseのままなら、条件に合う生徒はいなかったことが分かります。
Findで最初の1件を取得する
foreach文とif文で書いた検索は、Findを使うと1行で表せます。
Student foundStudent = students.Find(student => student.Name == "鈴木");
Findは、Listの先頭から順番に条件を確認し、最初に条件へ合った要素を返します。
if (foundStudent != null)
{
foundStudent.ShowScore();
}
else
{
Console.WriteLine("生徒が見つかりませんでした。");
}
名前が鈴木の生徒が見つかれば、そのStudentがfoundStudentに入ります。見つからなければnullになります。
ラムダ式の読み方
Findの中に書いた次の部分を、ラムダ式と呼びます。
student => student.Name == "鈴木"
今は、次のように読むとよいでしょう。
student:Listから取り出した1人の生徒=>:その生徒について、右側の条件を確認するstudent.Name == "鈴木":名前が鈴木と同じか
つまり、「生徒を1人ずつ確認して、名前が鈴木の生徒を探す」という意味です。最初からラムダ式を暗記する必要はありません。foreach文とif文を短く表した形だと考えてみてください。
Findで点数を条件に検索する
名前だけでなく、点数を条件にすることもできます。
Student foundStudent = students.Find(student => student.Score >= 80);
このListで最初に80点以上なのは、82点の佐藤さんです。そのため、foundStudentには佐藤さんが入ります。
88点の鈴木さんも条件には合っていますが、Findが返すのは最初の1件だけです。
FindAllで条件に合う全員を取得する
80点以上の生徒を全員取り出したい場合は、FindAllを使います。
List<Student> highScoreStudents =
students.FindAll(student => student.Score >= 80);
FindAllの検索結果は1人とは限らないため、戻り値もList<Student>です。
foreach (var student in highScoreStudents)
{
student.ShowScore();
}
実行すると、82点の佐藤さんと88点の鈴木さんが表示されます。75点の田中さんと65点の高橋さんは含まれません。
FindAllの結果が0件の場合
FindAllで条件に合う生徒がいない場合、nullではなく空のListが返されます。
List<Student> highScoreStudents =
students.FindAll(student => student.Score >= 100);
Console.WriteLine(highScoreStudents.Count); // 0
Countを確認すると、検索結果が何件あったか分かります。
Containsを使うときの注意
Containsは、指定した要素がListに含まれているかをtrueまたはfalseで返します。
Student student = students[0];
bool exists = students.Contains(student); // true
ただし、今回のようなStudentクラスでは、名前と点数が同じ別のインスタンスを作っても、同じ要素とは判断されません。
Student anotherStudent = new Student
{
Name = "田中",
Score = 75
};
bool exists = students.Contains(anotherStudent); // false
名前などの内容を条件に探したいときは、FindやFindAllを使う方が分かりやすいでしょう。
完成コード
using System;
using System.Collections.Generic;
namespace StudentListSearchTutorial
{
internal class Program
{
static void Main(string[] args)
{
List<Student> students = new List<Student>();
students.Add(new Student { Name = "田中", Score = 75 });
students.Add(new Student { Name = "佐藤", Score = 82 });
students.Add(new Student { Name = "鈴木", Score = 88 });
students.Add(new Student { Name = "高橋", Score = 65 });
Console.Write("検索する生徒の名前を入力してください:");
string searchName = Console.ReadLine();
Student foundStudent =
students.Find(student => student.Name == searchName);
if (foundStudent != null)
{
Console.WriteLine("生徒が見つかりました。");
foundStudent.ShowScore();
}
else
{
Console.WriteLine("生徒が見つかりませんでした。");
}
Console.WriteLine();
Console.WriteLine("80点以上の生徒を表示します。");
List<Student> highScoreStudents =
students.FindAll(student => student.Score >= 80);
foreach (var student in highScoreStudents)
{
student.ShowScore();
}
}
}
class Student
{
public string Name;
public int Score;
public void ShowScore()
{
Console.WriteLine($"{Name}さんの点数は{Score}点です。");
}
}
}
Visual Studioの設定によっては、Console.ReadLine()、Findの戻り値、Nameに関する警告が表示されることがあります。まずは検索条件と結果の流れに注目して、動きを確認してみましょう。
3つの方法の使い分け
- 検索の仕組みを確認したい:
foreach + if - 条件に合う最初の1件がほしい:
Find - 条件に合う全件がほしい:
FindAll - 同じ要素が含まれているかだけ知りたい:
Contains
初心者のうちは、まずforeach + ifで検索できることを確認し、その後でFindとFindAllへ書き換えると理解しやすくなります。
今回のまとめ
foreach文とif文で、Listを1件ずつ検索できるbreakで、見つかった後の繰り返しを終了できるFindで、条件に合う最初の1件を取得できるFindで見つからなかった場合はnullになるFindAllで、条件に合う全件を新しいListとして取得できるFindAllの結果が0件なら、空のListが返る- ラムダ式は、1件ずつ条件を確認する処理を短く表している
- Studentの内容を条件に探す場合は、
ContainsよりFindが分かりやすい
1件だけ探すならFind、条件に合う全員を探すならFindAllを使います。
まずは名前で1人を検索し、次に点数を条件として複数の生徒を取り出してみてください。
Listの基本を使って小さな作品を作りたい方は、次の記事でRandomとListを組み合わせたおみくじ作りに挑戦してみましょう。「C#でおみくじを作ろう!RandomとListを使った初心者向けミニ制作」へ進むと、ランダムな番号でListから結果を取り出す流れを学べます。








ディスカッション
コメント一覧
まだ、コメントがありません