2009-11-19 16 views
90

Can linq può essere utilizzato in qualche modo per trovare l'indice di un valore in un array?Trova l'indice di un valore in un array

Ad esempio, questo ciclo individua l'indice chiave all'interno di un array.

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

In realtà, anche ottenere la parola andrebbe bene. – initialZero

risposta

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

Che in realtà si ottiene l'indice intero e non l'oggetto, indipendentemente da ciò che classe personalizzata che hai creato

3

Prova questo ...

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

Questa sembra una soluzione molto debole rispetto alle risposte di Grizzly e masenkablast. masenkablast risponde alla domanda originale e Grizzly offre una soluzione migliore per trovare la parola, poiché la sua "var" finale sarà la parola effettiva e non un IEnumerable contenente 1 word. – James

6

Se si vuole trovare la parola che si può usare

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

Questo ti dà il primo elemento per il quale IsKey è vero (se ci potrebbe essere non si potrebbe voler utilizzare .FirstOrDefault()

Per ottenere sia l'elemento che l'indice è possibile utilizzare

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

linq è pazzo. Pensavo che i generici di Java fossero pazzi. Comunque, grazie per tutto l'aiuto. – initialZero

+0

Lanciare la pratica del valore di ritorno accettata o esiste un modo per definire il tipo di parola? – initialZero

+0

ok, mi sono inventato questo. DecodedMessageWord keyWord = words.Where (x => x.IsKey == true). Prima (); – initialZero

2

appena postato la mia implementazione di IndexWhere() metodo di estensione (con test di unità):

http://snipplr.com/view/53625/linq-index-of-item--indexwhere/

Esempio di utilizzo:

int index = myList.IndexWhere(item => item.Something == someOtherThing); 
+0

Non utilizzerei quella libreria, non implementa correttamente questi metodi. Ignora lo smaltimento. –

0
int index = -1; 
index = words.Any (word => { index++; return word.IsKey; }) ? index : -1; 
9
int keyIndex = words.TakeWhile(w => !w.IsKey).Count(); 
+0

+1 per la composizione dei metodi Linq esistenti – Slugart

+2

+1 ma, se l'articolo non esiste? Otterremo 0, ma l'indice è -1 –

+0

@ArsenMkrtchyan Se l'elemento non esiste, questo produce parole.Lunghezza –

46

Per gli array è possibile utilizzare: Array.FindIndex<T>:

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

Per gli elenchi è possibile utilizzare List<T>.FindIndex:

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

È inoltre possibile scrivere un metodo di estensione generico che funziona per qualsiasi 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; 
} 

Ed è possibile utilizzare LINQ così:

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

Si prega di notare che questo non sarà corto circuito il ciclo (itererà sempre sull'intera collezione) e genererà un'eccezione se la condizione non viene soddisfatta, piuttosto che restituire -1.

+2

C'è anche un [List (T) .FindIndex] (http://msdn.microsoft.com/en-us/library/ 0k601hd9.aspx) metodo – tdc

+0

@Paolo che ne dici di un elenco generato da Lambda? Ottengo l'errore di predicato. –

Problemi correlati