2010-09-30 15 views
6

Biorąc pod uwagę moją obecną metodę rozszerzenia:Powtórz LINQ kwerendy

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

pierwotnego stanu:

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

Aktualny wynik dla 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 

Czy istnieje sposób na pozbycie się tej pętli i możliwość zintegrowania powtórzenia z zapytaniem LINQ?

Najlepszy
Henrik

+0

dobrze .. wyniki powinny być w porządku .. Obrotowy 10 elementów 10 razy powinno skutkować w oryginalnym stanie. –

+0

Co to jest "gesamtRing"? Czy jest to "A B C D E F G H I J", czy jest to wynik po 1 rotacji? – dtb

+0

dodano oryginalną wartość dzwonka. –

Odpowiedz

3

Przejdź i i 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

Prawidłowe i bardzo eleganckie! Lubię to. –

+0

Warunek trójskładnikowy nie jest konieczny. 'i% = c.Count;' daje tę samą wartość. Podejrzewam, że różnica w wydajności jest niewielka, ale poprawa czytelności jest dość wysoka. – dss539

3

To powinno produkować takie same, jak oryginalnego rozwiązania i kompensuje -1 wydania:

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

Edytuj

mam umieścić to pod konsolą aplikacja, wyniki wyglądają tak samo dla mnie

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, dziękuję, ale to nadal wymaga pewnego rodzaju pętli. –

+0

Więc chcesz wyjściowy _entire_ siatki, a nie tylko wynik jednej metody rozszerzenia? To nie było jasne z pytania – amarsuperstar

+0

Nie, po prostu chcę wyniku. Przepraszam, jeśli nie wyjaśniłem tego. –

1

Aby napisać program konsoli całkowicie z Linq, jak o:

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(); 
    } 
} 
Powiązane problemy