- 締切済み
独自クラスの特定値のインデックスの取得
よろしくお願いします c#にて独自クラスの特定項目の値がtrueのインデックスを取得する方法をご教示願います。 一番最初に出現する位置でよいのでindexOfを使用しようとしましたが記述方法がわかりませんでした。 あるいは、せっかくのc#なのでlinqで実現可能でしたらlinqでの実現方法をご教示お願いします。 イメージは以下になります。 public class Test { public bool hi { get; set; } public string name { get; set; } } private void button1_Click(object sender, EventArgs e) { List<Test> test = new List<Test>(); test.Add(new Test() { name = "1-1", hi = true }); test.Add(new Test() { name = "2-1", hi = false }); test.Add(new Test() { name = "3-1", hi = false }); // 一番最初にhiがtrueのインデックスを取得したい // 上記だと1件目(0) } よろしくお願いします。
- みんなの回答 (1)
- 専門家の回答
みんなの回答
標準のLINQメソッドでやるとすると以下のような感じですね。 (見つからないときは -1 となる) var index = test .Select((elem, idx) => new { elem, idx, }) .Where(item => item.elem.hi) .Select(item => item.idx) .DefaultIfEmpty(-1) .First(); ただ、LINQは長さは決まっていないデータのシーケンスを扱うものなので、「インデクスを取得して~」というような処理とは思想があまり合いません。 なので、上記を見ての通り記述量も処理量も無駄が多くなります。 いまやろうとしていることがインデクスを取得してその要素にアクセスする、とかだったりしませんか?もしそうであれば、以下のようにインデクスは気にせず最初に条件に合う要素を取得するというほうがスマートかもしれませんよ。 (もちろんインデクス自体が必要な場合はあるので、いつもそれで済むわけではありませんが) var matchElem = test.FirstOrDefault(elem => elem.hi); いややはり必要なのはインデクスなのだという場合、最初の例の改良として、独自のLINQ拡張メソッドを用意して行う方法もあります。 internal static class CustomLinq { public static int SeqIndexOf<T>(this IEnumerable<T> self, Func<T, bool> predicate) { var index = -1; foreach (var elem in self) { index++; if (predicate(elem)) { break; } } return index; } } 例えば上記のような拡張メソッドを用意すれば、一時的な匿名クラスオブジェクトを介することもないので処理効率的にも良く、利用側も以下のようにさくっと書けます。 var index2 = test.SeqIndexOf(elem => elem.hi);
お礼
回答ありがとうございます。 この回答はまさにネットで探していた情報です!! 頑張って解析して勉強させていただきます!