Matt McManis
Matt McManis

Reputation: 4675

Convert 2D Array to 1D List with Row items in Consecutive Order

I have a 2D char array.

I want loop through and add each char + index in consecutive order to a new 1D list.

So the new 1D list will display as:

G0
V1
H2
F3
I4
E5
V6
A7
U8
G9
N10
L11
...

C#

char[,] array = new char[6,4] { 
    { 'G', 'V', 'H', 'F' },
    { 'I', 'E', 'V', 'A' },
    { 'U', 'G', 'N', 'L' },
    { 'G', 'X', 'F', 'W' },
    { 'E', 'N', 'L', 'H' },
    { 'A', 'H', 'V', 'B' }
};


List<string> matrixCharacters = new List<string>();


for (int m = 0; m < 24; m++) // marix positions 24
{
    for (int r = 0; r < 6; r++) // matrix rows 6
    {
        for (int c = 0; c < 4; c++) // matrix columns 4
        {
            matrixCharacters.Add(array[r,c].ToString() + r.ToString());
        }
    }
}

But I'm having trouble making a loop that can do it.

This displays:

http://rextester.com/RPRXM23687

G0
V0
H0
F0
I1
E1
V1
A1
U2
G2
N2
L2
...

Method 2 displays:

http://rextester.com/TYLJE96460

GVHF0
IEVA1
UGNL2
GXFW3
ENLH4
AHVB5

Upvotes: 1

Views: 1222

Answers (2)

Sergio0694
Sergio0694

Reputation: 4567

You can replace the loops along with having to manually create the list with a single LINQ query, this will also make the whole code more compact:

var list = array.Cast<char>().Select((c, i) => $"{c}{i}").ToList();

Let's take a look at how it works:

  • array.Cast<char>() - this flattens the 2D matrix into a linear array, or rather, it enumerates the items in the 2D array as if it was a linear array. It's useful in cases like this, where you're interested in going over each item, without having to actually create additional lists or copy the original data into another data structure.
  • Select((c, i) => $"{c}{i}") - this applies a selection function to each item in the previous sequence. Since we're calling this on the results of Cast<char>(), this will apply our function to each char in the original list. In this case, the function takes two parameters (c, i), a character and its index in the list, and returns the string $"{c}{i}". We're using string interpolation, so the values between the { } brackets will be our arguments in the lambda function. To recap, every item in the original array will be selected along with its index, and the result of this function will be a string containing the value itself, given by {c} and its index, given by {i}.
  • ToList() - this just creates a list with the resulting items from the previous query.

It's a good idea to long into the LINQ methods, as they're usually less error-prone than manual loops, in cases like this one.

A LINQ query might seem more obscure at the beginning, if you're new to C#, but in the long run it'll be well worth the effort, as it'll make you save a ton of times whenever you have to make some selection/filtering/query on a given set of items.

Upvotes: 3

Caius Jard
Caius Jard

Reputation: 74605

Ditch (remove from your code) the first loop with 24 iterations

Make the logic of your list add:

        matrixCharacters.Add(array[r,c].ToString() + (r * 4 + c).ToString());

variable r increments from 0 to 5. For each value of r, c increments from 0 to 3. This is why r*4+c counts from 0 to 23; it's like a base 4 number:

0*4+0=0
0*4+1=1
0*4+2=2
0*4+3=3
1*4+0=4 //c back to 0, r up to 1
...

Upvotes: 2

Related Questions