やりたいこと
以下のような自作クラスがあるとします。
class Member
{
public int ID;
public string Name;
// コンストラクタ
public Member(int id, string name)
{
ID = id;
Name = name;
}
}
上記クラスのインスタンスを保持するリストの中から名前が一致する要素をすべて検索して表示します。
void Sample()
{
// リストの内容を作成
MemberList.Add(new Member(1, "Sato"));
MemberList.Add(new Member(2, "Tanaka"));
MemberList.Add(new Member(3, "Suzuki"));
MemberList.Add(new Member(4, "Tanaka")); // 二人目の田中
// 探したい名前
string name = "Tanaka";
// 名前が一致するメンバー情報をすべて取得
Member[] members = FindAllMembersByName( name ); // ★これを実現したい
// 名前が一致するメンバーをすべて表示
foreach (var member in members)
{
System.Diagnostics.Debug.Print($"{member.Name} : ID={member.ID}");
}
}
実行結果
Tanaka : ID=2
Tanaka : ID=4
サンプル
foreachを使用
まずは基本の形。要素を先頭から順番にチェックして名前が一致する要素があったら、その要素をリストに保持。すべてチェックしたら配列にして返します。
Member[] FindAllMembersByName(string name)
{
var list = new List<Member>();
foreach (var member in MemberList)
{
if (member.Name == name) list.Add(member);
}
return list.ToArray(); ;
}
機能としては上記で十分ですが、もっと簡単な書き方があります。
FindAll()を使用
List<T>にはFind()メソッドがあります。この中に下記のようにラムダ式を記述することで上記foreachと同等の処理を記述できます。要素が見つからない場合には要素ゼロの配列が返る点も同等です。
※見つからない場合FindAll()は空のリストを返してくる。それをToArray()で要素ゼロの配列にしている。
Member[] FindAllMembersByName2(string name)
{
return MemberList.FindAll(member => member.Name == name).ToArray();
}
もちろん、サブ関数化せず直接FindAll()を使っても大丈夫です。好みで選択してください。私は役割が分かりやすくなるのでサブ関数化するのが好きです。