tags:

views:

172

answers:

3

i'm having a List<String> like

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

I need to create a new list (List<String>) with "MyList" . so the rows in the "MyList" becomes columns in the new List and the columns become rows

So the result will be like

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

now i'm using nested for loop to do this.

Is there any way to do this using LINQ or LAMBDA expression

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

Of course, this will break if the strings are not of identical length.

Ani
@ Ani : +1 `Enumerable.Range() ` should have two arguments (`.net 3.5`) .
Pramodh
Typo, sorry. I was 'manually copying' it by looking at the code I have written on an instance of VS I have open on another machine.
Ani
i think instead of `String.concat(...)` we have to use `new String(...)`
Pramodh
@Pramodh: That's a good idea, but `string.Concat` should work too.
Ani
+5  A: 

Here's a LINQPad script that does the trick:

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

Output:

101
001
101
000
100
000
Lasse V. Karlsen
@ Lasse : Nice solution......
Pramodh
This has a poteniel problem, in that for some types of `IEnumerable<>s`, after the .First(), it will not reset to the beginning for the `from s in string`, so you'll miss the first row. In fact, you need it to reset every time, so you may be better off accepting a `List<>` as the parameter.
James Curran
+2  A: 
        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);
Grozz