Howard
Howard

Reputation: 3758

How can I change an 2D array to a 2D list and then back to a 2D array again?

I thought searching SO would show me a hit regarding 2D lists to 2D arrays but it seems it's not as common as I had thought.

This is what I've got:

// init array
int[][] a = new int[10][10]; 

// change 2D array to 2D list
List<List<int>> b = a.Cast<List<int>>().ToList();

// change 2D list back to 2D array
???

How can I change b back to a 2D array? Also is the above correct?

Upvotes: 0

Views: 168

Answers (2)

xanatos
xanatos

Reputation: 111870

It's totally wrong. You can't get b in that way. And even the initialization is wrong. And in .NET there are two types of multidimensional arrays... True multidimensional arrays and jagged arrays...

Let's start... You are using a jagged array (I won't tell you what it's, or the difference, you didn't ask for it... if you need them, google for it)

int[][] a = new int[10][]; // see how you define it? 
// Only the first dimension can be  is sized here.

for (int i = 0; i < a.Length; i++)
{
    // For each element, create a subarray 
    // (each element is a row in a 2d array, so this is a row of 10 columns)
    a[i] = new int[10];
}

Now you have defined a 10x10 array jagged array.

Now a little LINQ:

You want a list:

List<List<int>> b = a.Select(row => row.ToList()).ToList();

you want back an array:

int[][] c = b.Select(row => row.ToArray()).ToArray();

The first expression means

foreach element of a, we call this element row `a.Select(row =>` <br>
make of this element a List `row.ToList()` and return it<br>
of all the results of all the elements of a, make a List `.ToList();`

The second is specular.

Now... Just out of curiosity, and if you had a true multidimensional array? then it was complex, very comples.

int[,] a = new int[10,10];

int l0 = a.GetLength(0);
int l1 = a.GetLength(1);

var b = new List<List<int>>(
               Enumerable.Range(0, l0)
                         .Select(p => new List<int>(
                                          Enumerable.Range(0, l1)
                                                    .Select(q => a[p, q]))));

var c = new int[b.Count, b[0].Count];

for (int i = 0; i < b.Count; i++)
{
    for (int j = 0; j < b[i].Count; j++)
    {
        c[i, j] = b[i][j];
    }
}

With a tricky (and horrible) LINQ expression we can "convert" a multidimensional array to a List<List<int>>. The road back isn't easily doable with LINQ (unless you want to use the List<T>.ForEach() that you shouldn't ever use, because it's not kosher, and then List<T>.ForEach() isn't LINQ)... But it's easily doable with two nested for ()

Upvotes: 1

undefined
undefined

Reputation: 34248

Something like this:

List<List<int>> lists = arrays.Select(inner=>inner.ToList()).ToList();

int[][] arrays = lists.Select(inner=>inner.ToArray()).ToArray();

Upvotes: 5

Related Questions