2010-11-02 6 views

risposta

22

avrei bisogno di più contesto, ma se sei solo ottenendo un indice in modo che si può chiamare .Skip, mi sento di raccomandare dare un'occhiata a .SkipWhile .

Se è davvero necessario l'indice, suggerirei di scrivere il proprio metodo di estensione .IndexOf.

+0

+1 per aver detto che probabilmente vuole usare 'SkipWhile', perché trovare l'indice e poi chiamare' Skip' enumera la query due volte – Gabe

+0

Così vicino ... ora voglio usare SkipWhile in congiunzione con un contatore, cioè lista. SkipWhile (myBusinessLogicCondition && list.Count - SkipIndex> someXnumber); – user494352

+0

user494352: Sembra che tu voglia dare un'occhiata alla lista di Jon.Seleziona(). SkipWhile() 'rispondi alla fine del suo post. – Gabe

6

È possibile proiettare le voci di elenco con i loro indici prima:

var item = list.Select((item, index) => new { Item = item, Index = index }) 
       .Where(pair => SomeCondition(pair.Item)) 
       .Select(result => result.Index); 
36

Certo, è abbastanza facile:

var index = list.Select((value, index) => new { value, index = index + 1 }) 
       .Where(pair => SomeCondition(pair.value)) 
       .Select(pair => pair.index) 
       .FirstOrDefault() - 1; 

Questo restituirà l'indice se trova qualcosa che corrisponde, o -1 altrimenti. Il +1 e -1 è quello di ottenere il comportamento per il caso in cui non ci sono corrispondenze. Se si sapeva che ci sarebbe sempre una partita, sarebbe più semplice:

var index = list.Select((value, index) => new { value, index }) 
       .Where(pair => SomeCondition(pair.value)) 
       .Select(pair => pair.index) 
       .FirstOrDefault(); 

Se sei felice di ottenere il resto della lista da quel punto in poi, è sicuramente SkipWhile tuo amico, come detto da Chris . Se desidera che il resto della lista e l'indice originale, che è troppo facile:

var query = list.Select((value, index) => new { value, index }) 
       .SkipWhile(pair => !SomeCondition(pair.value)) 

Che vi darà una sequenza di coppie { value, index } dal primo valore corrispondente SomeCondition.

+1

E 'un peccato che 'FirstOrDefault' non consente di specificare il valore di default, eh? – Gabe

+0

@Gabe: Sì :(Certo, sarebbe facile scrivere la tua implementazione ... –

+0

Grazie Jon, sto cercando di incorporare SkipWhile con un indice, piuttosto contare per vedere se ho saltato troppo. – user494352

14

Naturalmente la sua possibile utilizzare IEnumerable ...

public static class EnumerableExtension 
    { 

     public static int FirstIndexMatch<TItem>(this IEnumerable<TItem> items, Func<TItem,bool> matchCondition) 
     { 
      var index = 0; 
      foreach (var item in items) 
      { 
       if(matchCondition.Invoke(item)) 
       { 
        return index; 
       } 
       index++; 
      } 
      return -1; 
     } 
    } 
+1

+1. Normalmente preferisco più risposte linq-y come quelle di Jon, ma in questo caso questa soluzione è molto più semplice da guardare e capire cosa fa. E come metodo di estensione può ancora * essere usato * in un'espressione linq. Win-win. –

+0

L'uso di 'matchCondition.Invoke (item)' non è necessario. Puoi semplicemente fare 'matchCondition (item)'. – ErikE

24

Se davvero basta il primo indice poi contare quelli che non corrispondono:

var index = list.TakeWhile(t => !someCondition).Count() 
Problemi correlati