ループせずにリスト内のアイテムのインデックスを見つけるにはどうすればよいですか?
現在、これは非常に見栄えがよくありません-インデックスを取得するためだけに、同じアイテムのリストを2回検索します。
var oProp = something;
int theThingIActuallyAmInterestedIn = myList.IndexOf(myList.Single(i => i.Prop == oProp));
ループせずにリスト内のアイテムのインデックスを見つけるにはどうすればよいですか?
現在、これは非常に見栄えがよくありません-インデックスを取得するためだけに、同じアイテムのリストを2回検索します。
var oProp = something;
int theThingIActuallyAmInterestedIn = myList.IndexOf(myList.Single(i => i.Prop == oProp));
回答:
List.FindIndexメソッドはどうですか:
int index = myList.FindIndex(a => a.Prop == oProp);
このメソッドは線形検索を実行します。したがって、このメソッドはO(n)操作です。nはCountです。
アイテムが見つからない場合、-1を返します
単純型の場合は、「IndexOf」を使用できます。
List<string> arr = new List<string>();
arr.Add("aaa");
arr.Add("bbb");
arr.Add("ccc");
int i = arr.IndexOf("bbb"); // RETURNS 1.
編集:だけを使用しList<>
ていて、インデックスのみが必要な場合List.FindIndex
は、確かに最良のアプローチです。何か違うものが必要な人のために、ここではこの答えを残します(たとえば、の上にIEnumerable<>
)。
Select
述語でインデックスを取るのオーバーロードを使用して、リストを(インデックス、値)のペアに変換します。
var pair = myList.Select((Value, Index) => new { Value, Index })
.Single(p => p.Value.Prop == oProp);
次に:
Console.WriteLine("Index:{0}; Value: {1}", pair.Index, pair.Value);
または、インデックスのみが必要で、これを複数の場所で使用している場合、のような独自の拡張メソッドを簡単に作成できますがWhere
、元のアイテムを返す代わりに、述語と一致するアイテムのインデックスを返しました。
LINQを使用しない場合は、次のようにします。
int index;
for (int i = 0; i < myList.Count; i++)
{
if (myList[i].Prop == oProp)
{
index = i;
break;
}
}
この方法では、リストを1回だけ繰り返します。
FindIndex
外のLinqと同じ実装ですか?
文字列のリストのコードは次のとおりです。
int indexOfValue = myList.FindIndex(a => a.Contains("insert value from list"));
整数リストのコードは次のとおりです。
int indexOfNumber = myList.IndexOf(/*insert number from list*/);
IEnumerableのコピー/貼り付け可能な拡張メソッドは次のとおりです
public static class EnumerableExtensions
{
/// <summary>
/// Searches for an element that matches the conditions defined by the specified predicate,
/// and returns the zero-based index of the first occurrence within the entire <see cref="IEnumerable{T}"/>.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list">The list.</param>
/// <param name="predicate">The predicate.</param>
/// <returns>
/// The zero-based index of the first occurrence of an element that matches the conditions defined by <paramref name="predicate"/>, if found; otherwise it'll throw.
/// </returns>
public static int FindIndex<T>(this IEnumerable<T> list, Func<T, bool> predicate)
{
var idx = list.Select((value, index) => new {value, index}).Where(x => predicate(x.value)).Select(x => x.index).First();
return idx;
}
}
楽しい。
int index
ですか?