クラスをリストから効率的に検索したい
IndexOfの仕組みを知りたい
プログラムを制作するときモデルクラスを作成することがあると思います。
当然クラスをリストにして処理することもよくある方法です。
ではリストからオブジェクトを検索するときはどのような処理になるのでしょうか。
ForEach構文でループ処理が真っ先に思いつく方法かと思いますが、
実はメイン処理が1行で検索できる構文があるので紹介します。
IndexOfとは
まず[IndexOf]メソッドについて解説します。
[IndexOf]メソッドは、配列から最初から順に検索し、初めに一致したオブジェクトのインデックスを返すといった処理をします。
実際にコードを作成すると、下記のようになります。
protected void Method
{
List<string> nameList = new List<string>;
nameList.Add("たかし");
nameList.Add("はなこ");
nameList.Add("たろう");
nameList.Add("たかし");
int index = nameList.IndexOf("たかし"); //0がindexに挿入される
}
モデルクラス
今回の処理を照会する前に、リスト化されるモデルクラスを作成します。
public Class Employee
{
public enum KBN_AUTHORITY
{
ADMINISTRATOR,
GENERAL
}
//コンストラクタ
public Employee() { }
//コンストラクタオーバーロード
public Employee(string id) { this.id = id; }
//ID
private string ID { get; set; }
//氏名
private string Name { get; set; }
//権限
private KBN_AUTHORITY Authority { get; set; }
}
今回使用する上述の[Employee]クラスは、IDの被りが発生しないことを前提とします。
データベースの主キーのようにIDによって一意に検索することができるイメージです。
Equalsのオーバーライド
[IndexOf]でクラスを検索するためには、[Equals]メソッドをオーバーライド句で再定義する必要があります。
[IndexOf]はリストの先頭要素から順に[Equals]メソッドで比較し、初めに一致した要素のインデックスを返していると思われます。
[Equels]メソッドは、モデルクラス内で再定義します。
public Class Employee
{
public enum KBN_AUTHORITY
{
ADMINISTRATOR,
GENERAL
}
//コンストラクタ
public Employee() { }
//コンストラクタオーバーロード
public Employee(string id) { this.id = id; }
//ID
private string ID { get; set; }
//氏名
private string Name { get; set; }
//権限
private KBN_AUTHORITY Authority { get; set; }
//Equalsをオーバーライド
public override bool Equals(object obj)
{
if (obj == null) return false; //⓵
if (obj.GetType() != this.GetType()) return false; //⓶
return this.ID == ((Employee)obj).ID; //⓷
}
}
① | もし引数が[null]の場合、②のGetTypeがエラーとなるため、あらかじめNullチェックを行います。 |
② | もし引数が[Employee]クラスでない場合、③のキャストでエラーが発生するため、あらかじめ型チェックを行います。 |
③ | 引数の[ID]と自身(Employeeオブジェクト)のIDプロパティで比較を行い、一致すればTrueを返します。 |
IndexOfの実装
最後に、[IndexOf]メソッドを実装します。
これまでの部分で準備は完全に整っているため、実装はシンプルになります。
protected void Method
{
List<Employee> employeeList = new List<Employee>;
Employee emp1 = new Employee();
emp1.ID = "101";
emp1.Name = "たかし";
emp1.Authority = Employee.KBN_AUTHORITY.ADMINISTRATOR;
employee.Add(emp1);
Employee emp2 = new Employee();
emp2.ID = "201";
emp2.Name = "はなこ";
emp2.Authority = Employee.KBN_AUTHORITY.GENERAL;
employee.Add(emp2);
Employee emp3 = new Employee();
emp3.ID = "301";
emp3.Name = "たろう";
emp3.Authority = Employee.KBN_AUTHORITY.GENERAL;
employee.Add(emp3);
Employee emp4 = new Employee();
emp4.ID = "401";
emp4.Name = "たかし";
emp4.Authority = Employee.KBN_AUTHORITY.GENERAL;
employee.Add(emp4);
//検索処理
int index = employeeList.IndexOf(new Employee("101"));
}
IndexOfに指定するオブジェクトは検索するタイミングでインスタンス化しています。
この方法を使用すれば、メインメソッドでFor構文やForEach構文を使用することなくリスト検索を行うことが可能です。
これは特に複雑なロジックで有効でネストが1つ減るため、可読性の向上も期待できます。