2010-09-30 14 views
6

dado mi método de extensión actual:LINQ consulta

public static List<char> rotate(this List<char> currentList, int periodes) { 
    if (periodes != 1) { 
     int x = currentList.Count() - 1; 
     return rotate(currentList.Skip(x). 
      Concat(currentList.Take(x)).ToList<char>(), periodes - 1); 
    } 
    return currentList; 
} 

estado original:

ring = new List<char>() { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' }; 

El resultado actual de ring.rotate(10);

J A B C D E F G H I 
I J A B C D E F G H 
H I J A B C D E F G 
G H I J A B C D E F 
F G H I J A B C D E  Recursive Steps 
E F G H I J A B C D 
D E F G H I J A B C 
C D E F G H I J A B 
B C D E F G H I J A 

A B C D E F G H I J  Result 

¿Hay alguna forma de deshacerse de este bucle while y la posibilidad de integrar la repetición en la consulta LINQ?

Mejor
Henrik

+0

así .. sus resultados deben estar bien .. Rotación de 10 elementos 10 veces deben resultar en el estado original. –

+0

¿Qué es 'gesamtRing'? ¿Es "A B C D E F G H I J" o es el resultado después de 1 rotación? – dtb

+0

agregó el valor original de anillo. –

Respuesta

3

Saltar i y concat i

public static class Ex 
{ 
    public static List<char> Rotate(this List<char> c, int i) 
    { 
     i %= c.Count; 
     return c.Skip(i).Concat(c.Take(i)).ToList(); 
    } 
} 

class Program 
{ 
    static void Main() 
    { 
     List<char> chars = new List<char>(); 

     for (int i = 65; i < 75; ++i) 
     { 
      chars.Add((char)i); 
     } 

     var r1 = chars.Rotate(10); // A B C D E F G H I J 
     var r2 = chars.Rotate(1); // B C D E F G H I J A 
     var r3 = chars.Rotate(101); // B C D E F G H I J A 
     var r4 = chars.Rotate(102); // C D E F G H I J A B 

     Console.ReadLine(); 
    } 
} 
+1

¡Correcto y muy elegante! Me gusta. –

+0

No es necesario el condicional ternario. 'i% = c.Count;' da el mismo valor. Sospecho que la diferencia de rendimiento es minúscula, pero la mejora de legibilidad es bastante alta. – dss539

3

Esto debería producir el mismo que su solución original y compensa el tema -1:

public static List<char> rotate2(this List<char> currentList, int periodes) 
{ 
    int start = (currentList.Count - periodes) + 1; 
    return currentList.Skip(start).Concat(currentList.Take(start)).ToList(); 
} 

Editar

He puesto esto en una consola aplicación, los resultados parecen iguales para mí

class Program 
{ 
    static void Main(string[] args) 
    { 

     List<char> s = "ABCDEFGHIJ".ToList(); 

     for (int x = 0; x < 10; x++) 
     { 
      s.rotate(x+ 1).ForEach(Console.Write); 
      Console.WriteLine(); 
     } 
     Console.WriteLine(); 
     for (int x = 0; x < 10; x++) 
     { 
      s.rotate2(x + 1).ForEach(Console.Write); 
      Console.WriteLine(); 
     } 

     Console.ReadLine(); 
    } 
} 

static class so 
{ 
    public static List<char> rotate(this List<char> currentList, int periodes) 
    { 
     while (periodes != 1) 
     { 
      int x = currentList.Count() - 1; 
      return rotate(currentList.Skip(x). 
        Concat(currentList.Take(x)).ToList<char>(), periodes - 1); 
     } 
     return currentList; 
    } 

    public static List<char> rotate2(this List<char> currentList, int periodes) 
    { 
     int start = (currentList.Count - periodes) + 1; 
     return currentList.Skip(start).Concat(currentList.Take(start)).ToList(); 
    } 
} 
+0

Hmm, gracias, pero esto todavía requiere algún tipo de ciclo. –

+0

¿Desea el _entire_ output de la grilla, y no solo el resultado de un método de extensión? Eso no estaba claro en la pregunta – amarsuperstar

+0

No, solo quiero el resultado. Lo siento, si no lo dejé claro. –

1

para escribir el programa completo de la consola con LINQ, ¿qué tal:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var ring = Enumerable.Range(97, 10).Select(x => (char)x).ToList(); 

     Console.WriteLine(string.Join("\n", Enumerable.Range(1, 10).Select(x => new string(ring.rotate(x).ToArray())))); 

     Console.ReadLine(); 
    } 
}