Temukan indeks nilai dalam sebuah array


113

Dapatkah LINQ digunakan untuk menemukan indeks nilai dalam array?

Misalnya, loop ini menempatkan indeks kunci dalam sebuah array.

for (int i = 0; i < words.Length; i++)
{
    if (words[i].IsKey)
    {
        keyIndex = i;
    }
}

Sebenarnya, hanya mendapatkan kata-katanya juga tidak masalah.
initialZero

Jawaban:


183
int keyIndex = Array.FindIndex(words, w => w.IsKey);

Itu benar-benar memberi Anda indeks integer dan bukan objeknya, terlepas dari kelas khusus apa yang telah Anda buat


1
Mengapa ini tidak dijadikan metode ekstensi System.Linqsecara default? Di situlah segalanya seperti ini!
qJake

63

Untuk array, Anda dapat menggunakan Array.FindIndex<T>:

int keyIndex = Array.FindIndex(words, w => w.IsKey);

Untuk daftar, Anda dapat menggunakan List<T>.FindIndex:

int keyIndex = words.FindIndex(w => w.IsKey);

Anda juga dapat menulis metode ekstensi umum yang berfungsi untuk Enumerable<T>:

///<summary>Finds the index of the first item matching an expression in an enumerable.</summary>
///<param name="items">The enumerable to search.</param>
///<param name="predicate">The expression to test the items against.</param>
///<returns>The index of the first matching item, or -1 if no items match.</returns>
public static int FindIndex<T>(this IEnumerable<T> items, Func<T, bool> predicate) {
    if (items == null) throw new ArgumentNullException("items");
    if (predicate == null) throw new ArgumentNullException("predicate");

    int retVal = 0;
    foreach (var item in items) {
        if (predicate(item)) return retVal;
        retVal++;
    }
    return -1;
}

Dan Anda juga dapat menggunakan LINQ:

int keyIndex = words
    .Select((v, i) => new {Word = v, Index = i})
    .FirstOrDefault(x => x.Word.IsKey)?.Index ?? -1;

2
Ada juga Daftar (T) .FindIndex metode
tdc

@Paolo bagaimana dengan Daftar yang dihasilkan dari Lambda? Saya mendapatkan kesalahan predikat.
Mihir Patel

10
int keyIndex = words.TakeWhile(w => !w.IsKey).Count();

3
+1 tetapi, bagaimana jika item tidak ada? kita akan mendapatkan 0, tetapi indeksnya -1
Arsen Mkrtchyan

@ArsenMkrtchyan Jika item tidak ada, ini menghasilkan kata
Jim Balter

@ArsenMkrtchyan Anda menulis "kami akan mendapatkan 0" ... itu salah. Anda menulis "tetapi indeksnya -1" ... itu juga salah. -1 adalah indikator kegagalan yang umum, tetapi itu bukan satu-satunya yang mungkin. Nilai apa pun yang tidak berada dalam 0..words.Length-1 akan dilakukan.
Jim Balter

1
@JimBalter, maksud saya jika item tidak ada ekspresi akan mengembalikan 0, apa yang salah di dalamnya? Saya setuju bahwa -1 adalah indikator umum, tetapi setuju bahwa 99% kasus -1 adalah nilai yang diharapkan jika item tidak ada. setidaknya 0 salah ketika item tidak ada
Arsen Mkrtchyan

7

Jika Anda ingin mencari kata yang bisa Anda gunakan

var word = words.Where(item => item.IsKey).First();

Ini memberi Anda item pertama yang IsKey benar (jika mungkin ada non, Anda mungkin ingin menggunakan .FirstOrDefault()

Untuk mendapatkan item dan indeks, Anda dapat menggunakan

KeyValuePair<WordType, int> word = words.Select((item, index) => new KeyValuePair<WordType, int>(item, index)).Where(item => item.Key.IsKey).First();

Linq itu gila. Saya pikir obat generik Java gila. Bagaimanapun, terima kasih atas semua bantuannya.
initialZero

Apakah mentransmisikan nilai kembali merupakan praktik yang diterima atau adakah cara untuk menentukan jenis kata?
initialZero

ok, saya datang dengan ini. DecodedMessageWord keyWord = words.Where (x => x.IsKey == true). Pertama <DecodedMessageWord> ();
initialZero

5
@initialZero periksa kelebihannya karena First, dibutuhkan predikat, Anda tidak perlu ekstensi Where.
Yuriy Faktorovich

3

Coba ini...

var key = words.Where(x => x.IsKey == true);

2
Ini sepertinya solusi yang sangat lemah dibandingkan dengan jawaban Grizzly dan masenkablast. masenkablast menjawab pertanyaan asli dan Grizzly memberikan solusi yang lebih baik untuk menemukan kata tersebut, karena "var" terakhirnya adalah kata sebenarnya dan bukan <TSource> yang tidak terhitung banyaknya yang berisi 1 kata.
Yakobus


1

Solusi ini membantu saya lebih banyak, dari msdn microsoft :

var result =  query.AsEnumerable().Select((x, index) =>
              new { index,x.Id,x.FirstName});

queryadalah toList()pertanyaan Anda .


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.