2010-10-01 5 views
2

je vais avoir un List<String> commeC#: Comment manipuler la liste <String> en utilisant l'expression LINQ ou LAMBDA

List<String> MyList=new List<String> 
    { 
    "101010", 
    "000000", 
    "111000" 
    }; 

Je dois créer une nouvelle liste (List<String>) avec "MyList". de sorte que les lignes de la « MyList » devient colonnes dans la nouvelle liste et les colonnes deviennent des lignes

Ainsi, le résultat sera comme

{ 
    "101", 
    "001", 
    "101", 
    "000", 
    "100", 
    "000" 
    } 

maintenant je suis en utilisant la boucle nested for pour le faire.

Est-il possible de le faire en utilisant LINQ ou LAMBDA expression

+0

Que voulez-vous attendre à ce qu'il faut faire si les chaînes ne sont pas tous la même longueur? –

+0

@ Jon Skeet: Ce Scenerio ne se produira pas. Car avant d'ajouter des données à la liste, je les ferai de même longueur (la fonction 'PadLeft' sera appliquée) –

+0

Bien que vous puissiez sûrement le faire en utilisant les expressions LINQ et lambda, je doute sérieusement que le résultat soit plus facile à lire que votre imbriqué pour les boucles. =) – Jens

Répondre

1
var transposed = Enumerable.Range(0, MyList.First().Length) 
          .Select(rowIndex => new string(MyList.Select(str => str[rowIndex]).ToArray())) 
          .ToList(); 

Bien sûr, cela va briser si les chaînes ne sont pas de longueur identique.

+0

@ Ani: +1 'Enumerable.Range()' devrait avoir deux arguments ('.net 3.5'). –

+0

Typo, désolé. Je le «copiais manuellement» en regardant le code que j'avais écrit sur une instance de VS que j'avais ouvert sur une autre machine. – Ani

+0

Je pense qu'au lieu de 'String.concat (...)' nous devons utiliser 'new String (...)' –

6

Voici un script LINQPad qui fait l'affaire:

void Main() 
{ 
    List<String> MyList = new List<String> 
    { 
     "101010", 
     "000000", 
     "111000" 
    }; 
    Transpose(MyList).ToList().Dump(); 
} 

static IEnumerable<String> Transpose(IEnumerable<String> strings) 
{ 
    return from i in Enumerable.Range(0, strings.First().Length) 
      select new string((from s in strings select s[i]).ToArray()); 
} 

Sortie:

101 
001 
101 
000 
100 
000 
+0

@ Lasse: Belle solution ...... –

+0

Cela a un problème poteniel, en ce que pour certains types de 'IEnumerable <> s', après le .First(), il ne sera pas réinitialisé au début pour le' de s in string', vous manquerez donc la première rangée. En fait, vous en avez besoin pour réinitialiser à chaque fois, donc vous feriez mieux d'accepter un 'List <>' comme paramètre. –

2
 int n = myList[0].Length; // or whatever 

     var transposed = from ind in Enumerable.Range(0, n) 
         let sb = new StringBuilder() 
         select myList.Select(s => s[ind]).Aggregate(sb, (acc, next) => acc.Append(next)); 

     foreach (var s in transposed) 
      Console.WriteLine(s); 
Questions connexes