2013-08-01 6 views
121

Come posso trovare l'indice di un articolo in un elenco senza collegarlo?Come ottenere l'indice di un elemento in un elenco in un unico passaggio?

Attualmente questo non sembra molto bello - la ricerca attraverso la lista per lo stesso articolo due volte, solo per ottenere l'indice:

var oProp = something; 

int theThingIActuallyAmInterestedIn = myList.IndexOf(myList.Single(i => i.Prop == oProp)); 

risposta

277

Come circa il List.FindIndex Method:

int index = myList.FindIndex(a => a.Prop == oProp); 

Questo metodo esegue una ricerca lineare; pertanto, questo metodo è un'operazione O (n) , dove n è Count.

+0

Funziona ma non in LINQ, tuttavia +1 –

+2

Che ne dici di "int index'? –

+1

@DylanChensky ha codificato troppo JS – lenny

57

EDIT: Se siete solo utilizzando un List<> e si solo l'indice ha bisogno dell'indice, quindi List.FindIndex è davvero l'approccio migliore. Lascerò questa risposta qui per coloro che hanno bisogno di qualcosa di diverso (ad esempio sopra a qualsiasi IEnumerable<>).

Uso il sovraccarico di Select che prende un indice nel predicato, in modo da trasformare la vostra lista in un (indice, valore) coppia:

var pair = myList.Select((Value, Index) => new { Value, Index }) 
       .Single(p => p.Value.Prop == oProp); 

Poi:

Console.WriteLine("Index:{0}; Value: {1}", pair.Index, pair.Value); 

O se si solo vuoi l'indice e lo stai utilizzando in più punti, potresti facilmente scrivere il tuo metodo di estensione che era come Where, ma invece di restituire gli elementi originali, ha restituito gli indici di quelli elementi che corrispondono al predicato.

+0

Sembra che tutto ciò che vuole sia l'indice. Elenco <>. FindIndex (Predicate <>) è l'approccio migliore. Sebbene il titolo della domanda insinuasse altrimenti, la descrizione dell'OP è abbastanza chiara che ha bisogno solo dell'indice "int theThingIActuallyAmInterestedIn" –

+1

@LastCoder: Aha - ha perso FindIndex. Sì, sono completamente d'accordo. –

+0

Giusto per essere chiari, l'approccio "indice/valore -> singolo" è migliore "(qui significa essere più veloce in termini di Big-O) rispetto all'iterazione manuale due volte? Oppure il provider LINQ2bjects è abbastanza intelligente da ottimizzare una delle iterazioni? (Sto facendo presumere che sia Select che Single generalmente sono operazioni O (n)) – kai

11

Se non si desidera utilizzare LINQ, quindi:

int index; 
for (int i = 0; i < myList.Count; i++) 
{ 
    if (myList[i].Prop == oProp) 
    { 
     index = i; 
     break; 
    } 
} 

questo modo si effettua l'iterazione lista solo una volta.

+1

questo non è linq –

+14

@KingKing nessuno ha detto che lo è. –

+1

È la stessa implementazione di Linq 'FindIndex' di interesse? – Coops

53

Per i tipi semplici è possibile utilizzare "IndexOf":

List<string> arr = new List<string>(); 
arr.Add("aaa"); 
arr.Add("bbb"); 
arr.Add("ccc"); 
int i = arr.IndexOf("bbb"); // RETURNS 1. 
+2

Grazie! Così semplice ... – Teiki

+1

Funziona. – Ammar

3
  1. Soluzione semplice per trovare indice per qualsiasi valore stringa nella lista.

Ecco il codice per la Lista Di Stringa:

int indexOfValue = myList.FindIndex(a => a.Contains("//insert value from list")); 
  1. Soluzione semplice per trovare indice per qualsiasi valore intero nella lista.

Ecco il codice per l'elenco delle Integer:

int indexOfNumber = myList.IndexOf(//insert number from list); 
0

Ecco un/metodo di estensione pastosa capace copia per 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; 
    } 
} 

godere.

Problemi correlati