ฉันจะค้นหาดัชนีของรายการในรายการโดยไม่วนซ้ำได้อย่างไร
ขณะนี้สิ่งนี้ดูไม่ดีนัก - ค้นหารายการเดียวกันสองครั้งเพื่อรับดัชนี:
var oProp = something;
int theThingIActuallyAmInterestedIn = myList.IndexOf(myList.Single(i => i.Prop == oProp));
ฉันจะค้นหาดัชนีของรายการในรายการโดยไม่วนซ้ำได้อย่างไร
ขณะนี้สิ่งนี้ดูไม่ดีนัก - ค้นหารายการเดียวกันสองครั้งเพื่อรับดัชนี:
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
แต่แทนที่จะส่งคืนรายการต้นฉบับมันจะส่งคืนดัชนีของรายการเหล่านั้นที่ตรงกับภาคแสดง
Single()
ดำเนินการจะวนซ้ำไปตามลำดับนั้นและค้นหารายการเดียวที่ตรงกับเพรดิเคต สำหรับรายละเอียดเพิ่มเติมอ่านชุดบล็อก edulinq ของฉัน: codeblog.jonskeet.uk/category/edulinq
หากคุณไม่ต้องการใช้ LINQ ให้ทำดังนี้
int index;
for (int i = 0; i < myList.Count; i++)
{
if (myList[i].Prop == oProp)
{
index = i;
break;
}
}
วิธีนี้คุณกำลังทำซ้ำรายการเพียงครั้งเดียว
FindIndex
หรือไม่?
นี่คือรหัสสำหรับรายการของสตริง:
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;
}
}
สนุก.
หากใครสงสัยในArray
เวอร์ชั่นมันจะเป็นดังนี้:
int i = Array.FindIndex(yourArray, x => x == itemYouWant);
int index
ล่ะ