Bir dizideki bir değerin dizinini bulun


113

Linq, bir dizideki bir değerin dizinini bulmak için bir şekilde kullanılabilir mi?

Örneğin, bu döngü bir dizi içindeki anahtar dizinini bulur.

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

Aslında, sadece kelimeyi öğrenmek de iyi olur.
başlangıçSıfır

Yanıtlar:


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

Bu, hangi özel sınıfı oluşturduğunuza bakılmaksızın, size nesneyi değil, tamsayı dizinini alır.


1
Bu neden System.Linqvarsayılan olarak bir uzantı yönteminde yapılmadı ? Bunun gibi her şeyin olduğu yer orası!
qJake

63

Diziler için şunları kullanabilirsiniz Array.FindIndex<T>:

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

Listeler için şunları kullanabilirsiniz List<T>.FindIndex:

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

Ayrıca, aşağıdakilerden herhangi biri için çalışan genel bir uzantı yöntemi de yazabilirsiniz 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;
}

LINQ'i de kullanabilirsiniz:

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

2
Bir de bulunmaktadır listesi (T) .FindIndex yöntemi
TDC

@Paolo Lambda'dan oluşturulan bir Listeye ne dersiniz? Tahmin hatası alıyorum.
Mihir Patel

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

3
+1 ama, ya öğe yoksa? 0 alacağız, ancak endeks -1
Arsen Mkrtchyan

@ArsenMkrtchyan Öğe yoksa, bu kelimeler verir.Uzunluk
Jim Balter

@ArsenMkrtchyan "0 alacağız" yazmışsın ... bu yanlıştı. "Ama indeks -1" yazdın ... bu da yanlış. -1, yaygın bir başarısızlık göstergesidir, ancak tek olası olan bu değildir. 0..words.Length-1 dahilinde olmayan herhangi bir değer işe yarar.
Jim Balter

1
@JimBalter, demek istediğim öğe yoksa ifade 0 döndürür, bunda yanlış olan ne? -1'in ortak gösterge olduğuna katılıyorum, ancak madde mevcut olmadığında% 99 olgu -1'in beklenen değer olduğu aşikar olduğunu kabul ediyorum. Öğe yokken en az 0 yanlış
Arsen Mkrtchyan

7

Kullanabileceğin kelimeyi bulmak istiyorsan

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

Bu size IsKey'in doğru olduğu ilk öğeyi verir (eğer başka bir şey varsa kullanmak isteyebilirsiniz) .FirstOrDefault()

Hem öğeyi hem de dizini almak için kullanabileceğiniz

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

linq delilik. Java jeneriklerinin çılgın olduğunu düşündüm. Her neyse, tüm yardımlar için teşekkürler.
başlangıçSıfır

Dönüş değerini çevrim kabul edilebilir bir uygulama mı yoksa kelime türünü tanımlamanın bir yolu var mı?
başlangıçSıfır

tamam, bunu buldum. DecodedMessageWord keyWord = word.Where (x => x.IsKey == true). İlk <DecodedMessageWord> ();
başlangıçSıfır

5
@initialZero First, bir yüklem alır, bunun için aşırı yüklemeleri kontrol edin Where,.
Yuriy Faktorovich

3

Bunu dene...

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

2
Grizzly ve masenkablast'ın verdiği cevaplara kıyasla bu çok zayıf bir çözüm gibi görünüyor. masenkablast orijinal soruyu yanıtlar ve Grizzly kelimeyi bulmak için daha iyi bir çözüm sunar, çünkü son "var" kelimesi asıl kelime olacaktır ve 1 kelime içeren bir IEnumerable <TSource> değildir.
James


1

Bu çözüm, msdn microsoft'tan bana daha fazla yardımcı oldu :

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

querysenin olduğunu toList()sorgusu.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.