-2

My question is very similar to this one here: Rotate - Transposing a List<List<string>> using LINQ C#

Except my testing of the solutions brings to my attention that it works best on even arrays, and not uneven ones. The accepted solution and some others from the link above I grabbed out of curiosity all produced a transpose without infilling a lack of information on jagged lists.

{{"a"},
 {"b","c"}} 

would transpose into

{{"a","b"},
 {"c"}} 

instead of

{{"a","b"},
 {null,"c"}}.

My source data could have nothing if there's, say, three blank places of information at the end of what will become the list, it'll just get cut off without any nulls. I want the ability to insert nulls or some other specific value where lists that are not the longest length in the source data when I transpose. I know how the best way to handle it with just standard for loops, but I want a solution using Linq, something I'm unfortunately less familiar with.

Any help would be appeciated!

Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
pmackni
  • 307
  • 3
  • 12

1 Answers1

1

Well, if we want to transpose jagged collection, e.g.

  var source = new string[][] {
    new string[] {"a", "b", "c"},
    new string[] {"d"},
    new string[] {"e", "f"},
    new string[] {"g", "h", "i", "j"},
  };

we can compute number of columns: I've put .Count() so both List<List<string>> and string[][] will do.

  int columns = source.Max(line => null == line ? 0 : line.Count());

and then if we want to exclude nulls filter out lines which don't have required number of items:

  // Change .ToArray() to .ToList() if you want to have jagged List
  var result = Enumerable
    .Range(0, columns)
    .Select(c => source
       .Where(line => line != null && line.Count() > c)
       .Select(line => line[c])
       .ToArray())
    .ToArray();

Let's have a look:

  string report = string.Join(Environment.NewLine, result
    .Select(line => string.Join(" ", line.Select(c => c ?? "-"))));

  Console.Write(report);

Outcome:

a d e g
b f h
c i
j

Note, that transposing with nulls for holes will be

var result = Enumerable
  .Range(0, columns)
  .Select(c => source
     .Select(line => line == null || line.Count() <= c ? null : line[c])
     .ToArray())
  .ToArray();

Outcome:

a d e g
b - f h
c - - i
- - - j
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215