2009-04-22 15 views
13

Voglio ottenere l'elemento successivo in un elenco e se l'elenco è alla fine voglio il primo elemento. Quindi voglio solo che cerchi in altre parole.Elenco <> Ottieni l'elemento Next o ottieni il primo

List<int> agents = taskdal.GetOfficeAgents(Branches.aarhusBranch); 
    if (lastAgentIDAarhus != -1) 
    { 
     int index = agents.IndexOf(lastAgentIDAarhus); 
     if (agents.Count > index + 1) 
     { 
      lastAgentIDAarhus = agents[index + 1]; 
     } 
     else 
     { 
      lastAgentIDAarhus = agents[0]; 
     } 
    } 
    else 
    { 
     lastAgentIDAarhus = agents[0]; 
    } 

Sono abbastanza dispiaciuto con la mia soluzione sopra indicato, fatemi sapere se si dispone di una migliore :)

risposta

20
lastAgentIDAarhus = agents[index == -1 ? 0 : index % agents.Count]; 

l'uso dell'operatore MOD % costolette di atuomatically l'indice per la gamma di possibili indici.

L'operatore modulo è il complimento all'operatore DIV (/) e restituisce il resto di una divisione di due numeri interi. Ad esempio, se dividi 9 per 6, il risultato è 1 con un resto di 3. L'operatore MOD chiede il 3.

+0

wow questa è una soluzione estremamente pulita se funziona :) cura di spiegarlo un po '? –

+0

l'operatore mod fa un modulo, che è esattamente quello che volevi. Se è possibile inizializzare l'indice a 0 anziché a -1, è possibile utilizzare: lastAgentIDAarhus = agent [index% (agents.Count - 1)] – configurator

+3

Penso che dovrebbe essere 'index% (agents.Count)' –

2

Non una grande differenza, ma almeno un po 'meno codice (almeno nell'editor); o)

List<int> agents = taskdal.GetOfficeAgents(Branches.aarhusBranch); 
if (lastAgentIDAarhus != -1) 
{ 
    int index = agents.IndexOf(lastAgentIDAarhus); 
    lastAgentIDAarhus = (agents.Count > index + 1 ? agents[index + 1] : agents[0]); 
} 
else 
{ 
    lastAgentIDAarhus = agents[0]; 
} 
4

Come presa leggermente diversa su questo, ecco un metodo di estensione che è possibile utilizzare per rendere qualsiasi IEnumerable ' circolare'

public static IEnumerable<T> AsCircularEnumerable<T>(this IEnumerable<T> enumerable) 
    { 
    var enumerator = enumerable.GetEnumerator(); 
    if(!enumerator.MoveNext()) 
     yield break; 

    while (true) 
    { 
     yield return enumerator.Current; 
     if(!enumerator.MoveNext()) 
     enumerator = enumerable.GetEnumerator(); 
    } 
    } 

così si potrebbe utilizzare che come questo

var agents = new List<int> {1, 2, 3, 4, 123, 234, 345, 546}; 

    foreach(var i in agents.AsCircularEnumerable()) 
    { 
    Console.WriteLine(i); 
    } 

che sarà solo andare avanti ... :)

+0

se ci sono 3 elementi in una lista, e se io uso un valore di indice di 4 o 5 - per ottenere un elemento nella lista - otterrò il primo e il secondo elemento della lista? – BKSpurgeon

+0

Non sono sicuro di cosa intendi. Se stai chiedendo informazioni sull'indicizzazione usando la soluzione che ho delineato sopra, dato che non si tratta di un elenco, è un oggetto IEnumerable e non puoi utilizzare un indicizzatore su un oggetto IEnumerable, quindi no, non lo farai. È possibile utilizzare qualcosa come agenti.AsCircularEnumerable(). Skip (10) .First() invece. –

11

O semplicemente:

public static T NextOf<T>(this IList<T> list, T item) 
{ 
    return list[(list.IndexOf(item) + 1) == list.Count ? 0 : (list.IndexOf(item) + 1)]; 
} 

Esempio:

List<string> names = new List<string>(); 

names.Add("jonh"); 
names.Add("mary"); 

string name = String.Empty;  

name = names.NextOf(null); //name == jonh 

name = names.NextOf("jonh"); //name == mary 

name = names.NextOf("mary"); //name == jonh 
3

mi piace Vinicius's idea di utilizzare un metodo di estensione. Sfortunatamente il codice che ha postato genererà un'eccezione. Questo si basa sulla sua, ma non un'eccezione ed è molto semplice e facile da leggere (IMHO):

public static T Next<T>(this IList<T> list, T item) 
{ 
    var nextIndex = list.IndexOf(item) + 1; 

    if (nextIndex == list.Count) 
    { 
     return list[0]; 
    } 

    return list[nextIndex]; 
} 

verrà restituito il primo elemento della lista se l'oggetto passato in non è in l'elenco, dal list.IndexOf(item) restituirà -1 in tal caso;

+0

Koveras, dove si solleverà un'eccezione? –

+0

Ricorda quell'elenco.IndexOf (elemento) restituirà -1 se non viene trovato alcun elemento. –

+0

Questa è davvero una buona idea per un'estensione. L'ho modificato un po 'e l'ho implementato :) – etalon11

0

Cosa ne pensi se aggiungiamo qualche controllo per evitare errori comuni?

public static class ListExtensions 
{ 
    public static TType Next<TType>(this IList<TType> list, TType item) 
    { 
     if (list == null) return default(TType); 

     var itemIndex = list.IndexOf(item); 
     if (itemIndex < 0) return list.FirstOrDefault(); 

     var nextIndex = itemIndex + 1; 

     return nextIndex >= list.Count 
      ? list.FirstOrDefault() 
      : list[nextIndex]; 
    } 
} 
-4

stringa riga = righe [lines.FindIndex (x => x.Contains (articolo)) + 1];

Problemi correlati