1. for文回して探す
int index = -1; for (int i= 0; i < _params.Count; i++) { /* 条件式 */ if (_params[i] == ○○) { index = i; break; } } // _params はList型の変数です
どの言語でもできそうなシンプルなやつです。
上記のコードは条件にあった最初のインデックスを返します。
最後のインデックスにしたい場合は、break;
を消せばOKですね。
見つからない場合は初期化時の値になります。今回のだと-1 ですね
2. FindIndexを使う
int index = _params.FindIndex(x => '条件式');
List
クラス専用のメンバメソッドです。条件にあう最初の要素のインデックスを返します。
見つからない場合は -1 が返ってきます
通常の配列だとこのメソッドがないので使えないので注意が必要ですね。
3. System.Linqを使う
int index = _params.Select((item, index) => new { Index = index, Value = item }) .Where(x => '条件式') .Select(x => x.Index) .DefaultIfEmpty(-1) .First();
上記コードで他のパターンと同じ結果になります。
1回のメソッドチェーンで済ますにはこうなりました。
:かなり複雑なコードですよね笑。 *
解説はしますが、長いので読み飛ばしてもらってもOKです。
コードの解説
System.Linq
は要素の抽出には強いのですがインデックスを見つけるのは苦手なんです。
List
クラスにおけるFindIndex
に相当するメソッドが御座いません。
なのでメソッドチェーンで無理くりインデックスを抽出します。
Select
を使ってインデックスと要素の2つを持つ匿名クラスに射影しています。Where
で条件に合うものだけを抽出します。↑で分解した要素部分で判定しています。Select
でインデックスだけの配列になるように射影しています。DefaultIfEmpty
で条件にあったものが見つからない場合に要素を1個追加します。今回は -1 という要素を追加しています。First
は複数見つかった場合に最初の要素(インデックス)を返します。
試行錯誤
First
は例外吐く可能性を秘めているのですがDefaultIfEmpty
をかますことで要素が0の時がなくなるので例外がでないようになっています。
※配列の要素数が元々0だったとしてもこれで防げます。
元々はFirst
ではなくFirstOrDefault
を使っていたのですが、これだと見つからない場合にdefault値が返ります。
数値型のdefault値は0になります。
この0が少しやっかいで、配列の0番目が該当したのか、見つからなくて0だったのかが判断つかないからです。
といういうのものありFirstOrDefault
だけだとダメということになりました。
default値について公式ページをご参照くださいませ。