3

If you have an array like string[][], what's the smartest way to convert it to a regular multidimensional array like string[,] assuming the former array is rectangular (not jagged)?

The only approach I can think of is to get the dimensions, declare a multidimensional array with those dimensions, then loop through the source array and populate the new array. But I was wondering if there were any simpler solutions.

Dalal
  • 1,096
  • 2
  • 17
  • 38
  • 1
    What problems do you have with your proposed solution? In what way is it not sufficient for your needs? – Servy Aug 16 '13 at 15:31
  • possible duplicate of [Convert a jagged array to a 2D array directly without iterating each item?](http://stackoverflow.com/questions/11438587/convert-a-jagged-array-to-a-2d-array-directly-without-iterating-each-item) – BartoszKP Aug 16 '13 at 15:32
  • 1
    Also, why do you prefer `[,]` over `[][]`? Usually its the other way around. – SimpleVar Aug 16 '13 at 15:32
  • @YoryeNathan Well, a multidimensional array has improved memory locality. It can be an advantage or a disadvantage, depending on the situation. – Servy Aug 16 '13 at 15:33
  • possible duplicate of [jagged arrays <-> multidimensional arrays conversion in ASP.NET](http://stackoverflow.com/questions/3010219/jagged-arrays-multidimensional-arrays-conversion-in-asp-net) – Ehsan Aug 16 '13 at 15:34
  • @BartoszKP The linked question has no relevance the OP as the answer is to some specific problem which does not concern him. It has no use here. – SimpleVar Aug 16 '13 at 15:34
  • @BartoszKP He's *not* asking how to do the copy without iterating. He's asking for the simplest way of doing it, knowing that he has to iterate. So that's not really a dup. – Servy Aug 16 '13 at 15:35
  • Have you tried looking into `Array.CopyTo` and `arr2d.SelectMany(x => x)`? `memcpy` might also be useful since `[,]` is just like a normal `[]` in memory. – SimpleVar Aug 16 '13 at 15:37
  • @YoryeNathan Array.CopyTo only works for single dimensional arrays. `SelectMany` wouldn't create a multidimensional array; it would create a single dimensional array. – Servy Aug 16 '13 at 15:37
  • @Servy Yes, but you can then copy the content of that array into the multidimensional one. I wasn't sure if `Array.CopyTo` has an overload for multidimensional or not, but for that he can use `memcpy`. – SimpleVar Aug 16 '13 at 15:38
  • 1
    @YoryeNathan How is it any easier to copy the data from a single dimensional array to a multidimensional array than to copy it from a jagged array? Also note that doing two copies instead of one would have *dramatic* performance costs. Most likely prohibitively so. As for scrapping managed code and copying the underlying memory directly, you could only do that from a single dimensional array, and that doesn't seem like it would be simpler at all. It seems quite a bit more complex. – Servy Aug 16 '13 at 15:39
  • @YoryeNathan, I want it mainly because I'm tying into existing code that needs [,] as input. – Dalal Aug 16 '13 at 15:40
  • @Servy, I asked this mainly out of curiosity. I've seen some very elegant LINQ-style solutions in the past. While my solution would work, a one-line solution would be nice, but so would any alternative solution that teaches me a new technique. – Dalal Aug 16 '13 at 15:40
  • @Dalal LINQ, as a rule, doesn't play nice with multidimensional arrays. – Servy Aug 16 '13 at 15:41
  • There is no simpler solution.. – Dialecticus Aug 16 '13 at 15:40

1 Answers1

0

It's just for fun: totally agree that's an overkill and the very best way is the normal iteration.

    //example jagged array
    string[][] ja = new string[2][];

    for (int i = 0; i < 2; i++)
        ja[i] = Enumerable.Range(0, 3).Select(k => "Cell [" + i + "," + k + "]").ToArray();

    //conversion to a 2D-array
    string[,] ka = new[] { new string[ja.Length, ja[0].Length] }
        .Select(_ => new { x = _, y = ja.Select((a, ia) => a.Select((b, ib) => _[ia, ib] = b).Count()).Count() })
        .Select(_ => _.x)
        .First();

    //dump result
    for (int i = 0; i < 2; i++)
        for (int k = 0; k < 3; k++)
        {
            Console.WriteLine(ka[i, k]);
        }

Almost unreadable, but it works (at least when the initial array is not empty/malformed).

Mario Vernari
  • 6,649
  • 1
  • 32
  • 44
  • Very cool. Thanks for the neat solution. And I agree that perhaps normal iteration is indeed the best solution. Correct answer. – Dalal Aug 16 '13 at 18:43