2009-04-22 21 views
13

Quiero obtener el siguiente elemento en una lista y si la lista está en su final, quiero el primer elemento. Así que solo quiero que circule en otras palabras.Lista <> Obtener elemento siguiente u obtener el primer

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]; 
    } 

estoy bastante disgustado con mi propia solución que se muestra arriba, que me haga saber si usted tiene una mejor :)

Respuesta

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

el uso del operador MOD % chuletas atuomatically el índice para la gama de posibles índices.

El operador de módulo es el complemento para el operador DIV (/) y devuelve el resto de una división de dos números enteros. Por ejemplo, si divide 9 por 6, el resultado es 1 con un resto de 3. El operador MOD solicita 3.

+0

guau que es una solución extremadamente buena si eso funciona :) cuidado de explicarlo un poco? –

+0

el operador de mod hace un módulo, que es exactamente lo que quería. Si pudiera inicializar el índice en 0 en lugar de -1, podría usar: lastAgentIDAarhus = agents [index% (agents.Count - 1)] – configurator

+3

Creo que debería ser 'index% (agents.Count)' –

2

No es una gran diferencia, pero al menos algo de código de menos (al menos en el 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

Como punto de vista ligeramente diferente, este es un método de extensión que puede usar para hacer cualquier IEnumerable ' circular'

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(); 
    } 
    } 

lo que podría utilizar que como esto

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

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

lo cual va a seguir adelante ... :)

+0

si hay 3 elementos en una lista, y si uso un valor de índice de 4 o 5 para acceder a un elemento en la lista, ¿obtendré el primer y el segundo elemento de la lista? – BKSpurgeon

+0

No estoy seguro de lo que quieres decir. Si está preguntando sobre la indexación usando la solución que describí anteriormente, entonces, como esta no es una lista, es un IEnumerable y no puede usar un indexador en un IEnumerable, entonces no, no lo hará. Puede usar algo como agents.AsCircularEnumerable(). Skip (10) .First() en su lugar. –

11

O simplemente:

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

Ejemplo:

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

me gusta Vinicius's idea de la utilización de un método de extensión. Lamentablemente, el código que publicó arrojará una excepción. Esto se basa en la suya, pero no será una excepción y es muy sencillo y fácil de leer (en mi humilde opinión):

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]; 
} 

devolverá el primer elemento de la lista si el artículo que pasó no está en la lista, ya que list.IndexOf(item) devolverá -1 en ese caso;

+0

Koveras, ¿dónde se presentará una excepción? –

+0

Recuerde que list.IndexOf (elemento) devolverá -1 si no se encuentra ningún elemento. –

+0

Esto es realmente una buena idea para una extensión. Lo modifiqué un poco y lo implementé :) – etalon11

0

¿Qué opinas si añadimos algunos controles para evitar errores comunes?

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

línea de cuerda = líneas [lines.FindIndex (x => x.Contains (elemento)) + 1];

Cuestiones relacionadas