2013-01-05 6 views
8

diciamo, abbiamo una lista conElenco <T> .FindIndex per più risultati?

List<int> lst = new List<int>(); 
lst.Add(20); 
lst.Add(10); 
lst.Add(30); 
lst.Add(10); 
lst.Add(90); 

Se ho bisogno di ottenere l'indice del primo elemento che è di 20 userei

FindIndex() 

Ma esiste un metodo che può essere utilizzato per più risultati? Diciamo che mi piacerebbe avere l'indice degli elementi con il numero 10.

So che esiste un metodo FindAll() ma questo mi dà un nuovo Elenco degli indici.

Il metodo migliore (?) Sarebbe ottenere un array di indici.

+0

Mi chiedo perché hai bisogno degli indici. – Adam

risposta

11

Il più grande svantaggio del seguente codice è che usa -1 come numero magico, ma in caso di indici è innocuo.

var indexes = lst.Select((element, index) => element == 10 ? index : -1). 
    Where(i => i >= 0). 
    ToArray(); 
5

Una possibile soluzione è questa:

var indexes = lst.Select((item, index) => new { Item = item, Index = index }) 
       .Where(v => v.Item == 10) 
       .Select(v => v.Index) 
       .ToArray(); 

Prima di selezionare tutti gli oggetti e il loro indice, poi si filtra sulla voce e, infine, si selezionano gli indici

Aggiornamento: If vuoi incapsulare la soluzione mia o di Eve puoi usare qualcosa come

public static class ListExtener 
{ 
    public static List<int> FindAllIndexes<T>(this List<T> source, T value) 
    { 
     return source.Select((item, index) => new { Item = item, Index = index }) 
         .Where(v => v.Item.Equals(value)) 
         .Select(v => v.Index) 
         .ToList(); 
    } 
} 

E poi devi usare qualcosa di simile a:

List<int> lst = new List<int>(); 
lst.Add(20); 
lst.Add(10); 
lst.Add(30); 
lst.Add(10); 
lst.Add(90); 


lst.FindAllIndexes(10) 
    .ForEach(i => Console.WriteLine(i)); 
Console.ReadLine(); 
+0

Penso che la soluzione fornita da Eve funzionerà meglio, ma ho pubblicato il mio come un modo per mostrarti di pensare passo dopo passo all'inizio – TimothyP

+1

checkout [MSDN] (http://msdn.microsoft.com/en-us/ library/bb534869.aspx) per un altro esempio che utilizza lo stesso approccio – Matthias

2

solo per dare un'altra soluzione:

Enumerable.Range(0, lst.Count).Where(i => lst[i] == 10) 

E naturalmente può essere fatto un metodo di estensione:

public static IEnumerable<int> FindAllIndices<T>(this IList<T> source, T value) 
{ 
    return Enumerable.Range(0, source.Count) 
    .Where(i => EqualityComparer<T>.Default.Equals(source[i], value)); 
} 
Problemi correlati