DEV Community

Alexander Rovang
Alexander Rovang

Posted on

2D arrays vs. Nested arrays

At some point in the Leetcode/Hackerrank code challenges you start to see the phrase "2D array" a lot (also known as 2-Dimensional arrays). We learned a lot about nested arrays at my bootcamp, but this other naming convention never came up, so it was a little confusing to see the first time. This post is about clarifying the connection for myself (and maybe you?).

The idea of a nested array is pretty simple. You have an array, and inside that array you have one or more arrays as elements.

let myArray = [[1,2,3],[4,5,6]]
Enter fullscreen mode Exit fullscreen mode

If we were to access an element in that outer array, we would call it via single bracket notation and the appropriate index.

myArray[1]     // [4,5,6]
Enter fullscreen mode Exit fullscreen mode

To call an element inside one of the inner arrays, we would need to add a second bracket.

myArray[1][2]     // 6
Enter fullscreen mode Exit fullscreen mode

For months I had visualized these nested arrays exactly as you're seeing them above: in a linear fashion. And, yes, I realize that computers don't care about the optics of arrays, but being a highly visual person it was an easy way for me to understand them. Even a nested array with a lot of elements I thought of in a straight line.

let longArray = [[a,f,x,d],[q,l],[m,c,u,t,i],[w],[b,g,o]]
Enter fullscreen mode Exit fullscreen mode

(Also, I took way too long deciding which letters looked good together just now.)

But when I started seeing the new and scary 2D array problems they were often shown like this.

1  6  3  4
2  8  5  0
9  2  7  7
3  5  0  2
Enter fullscreen mode Exit fullscreen mode

This was usually the point at which my mind shut down and I went for a run.

There were 3 problems I had with this structure.

1) No brackets [scare factor: 10]
2) Perfect square structure
(Can't nested arrays have different numbers of elements in each internal array? How could these possibly be the same thing??)
3) Non-linear [Heart stops].

Let's go ahead and solve these one at a time.

Brackets.

[
  [1, 6, 3, 4],
  [2, 8, 5, 0],
  [9, 2, 7, 7],
  [3, 5, 0, 2]
]
Enter fullscreen mode Exit fullscreen mode

Great. Done.
[insert huge sigh of relief here]

Square structure.
YES. Nested arrays CAN have a different numbers of elements. Technically I suppose it's possible for a 2D array to have different numbers of elements, but 99% of the code challenges I've seen are geared toward grid structures like you see above because they are 1000 times easier to access and manipulate. It's like color theory. All pinks are in the red family, but reds aren't considered part of the pink family. Just because a 2D array happens to have a square or rectangular structure doesn't mean it's not still a nested arrayed at heart.

Non-linear pattern.

[
  [1, 6, 3, 4],
  [2, 8, 5, 0],
  [9, 2, 7, 7],
  [3, 5, 0, 2]
]

[[1, 6, 3, 4],[2, 8, 5, 0],[9, 2, 7, 7],[3, 5, 0, 2]]
Enter fullscreen mode Exit fullscreen mode

Literally the same thing.

So why write it like a grid? Here's where it gets interesting. My guess is that grid notation is used to help you better visualize (oh, the irony) the methods of access.

Let's look at a pretty common javascript algorithm: the nested for-loop.

for(let i = 0; i < myArray.length; i++){
     for(let j = 0; j < myArray.length; j++{
          //your code here
     }
}
Enter fullscreen mode Exit fullscreen mode

Note that this particular loop starts at the very beginning of the first nested array and works its way through each internal array from left to right. If we visualize this is in a linear pattern, the loop access would look something like this.

let myArray = [[1, 6, 3, 4],[2, 8, 5, 0],[9, 2, 7, 7],[3, 5, 0, 2]]
//1st element:  myArray[i][j] = myArray[0][0] = 1
//2nd element:  myArray[i][j+1} = myArray[0][1] = 6
//3nd element:  myArray[i][j+2} = myArray[0][2] = 3
Enter fullscreen mode Exit fullscreen mode

Not terrible. But what if for some reason we needed to start at the end of each internal array and search backwards? Then the loop would look like this...

for(let i = 0; i < myArray.length; i++){
     for(let j = myArray.length; j >=0; j--{
          //your code here
     }
}
Enter fullscreen mode Exit fullscreen mode

... and the corresponding results would look like this.

let myArray = [[1, 6, 3, 4],[2, 8, 5, 0],[9, 2, 7, 7],[3, 5, 0, 2]]
//1st element:  myArray[i][j] = myArray[0][3] = 4
//2nd element:  myArray[i][j+1} = myArray[0][2] = 3
//3nd element:  myArray[i][j+2} = myArray[0][1] = 6
Enter fullscreen mode Exit fullscreen mode

Starting to get a little confusing. Now let's say you wanted to check the first element in the first array, the second element in the second array, the third in the third, and so on?

for(let i = 0, j = 0; i < myArray.length; i++, j++){
     //your code here
}
let myArray = [[1, 6, 3, 4],[2, 8, 5, 0],[9, 2, 7, 7],[3, 5, 0, 2]]
//1st element:  myArray[i][j] = myArray[0][0] = 1
//2nd element:  myArray[i][j+1} = myArray[1][1] = 8
//3nd element:  myArray[i][j+2} = myArray[2][2] = 7
Enter fullscreen mode Exit fullscreen mode

If you're thinking about your nested arrays in a linear fashion, that looks like a hot mess. But turn it into it's 2D cousin...

[
  [1, 6, 3, 4],
  [2, 8, 5, 0],
  [9, 2, 7, 7],
  [3, 5, 0, 2]
]
Enter fullscreen mode Exit fullscreen mode

...and suddenly it becomes very obvious that you're just going along a diagonal in a square.

Now, if you google tutorials on 2D arrays you'll find that they consistently talk about "rows" and "columns". Which makes perfect sense when you're looking at a grid. But again, it's a little confusing when thinking about nested arrays. Let's take another look at the original example of javascript nested for-loops.

for(let i = 0; i < Arr.length; i++){
     for(let j = 0; j < Arr.length; j++{
          //your code here
     }
}
Enter fullscreen mode Exit fullscreen mode

Remember that the "i" in this algorithm represents the indices of the OUTER array. Those are the rows.

// Arr[i]
     [                                
          [1,   6,   3,   4],         // Arr[0]
          [2,   8,   5,   0],         // Arr[1]
          [9,   2,   7,   7],         // Arr[2]
          [3,   5,   0,   2]          // Arr[3]
     ]
Enter fullscreen mode Exit fullscreen mode

The columns, the indices of the INNER arrays, are the "j".

//                 [j]        [j]        [j]        [j]
//           Arr[i][0]  Arr[i][1]  Arr[i][2]  Arr[i][3]
           [                                           
                  [1,        6,        3,        4],   
                  [2,        8,        5,        0],   
                  [9,        2,        7,        7],   
                  [3,        5,        0,        2]    
          ]
Enter fullscreen mode Exit fullscreen mode

The thing that took me awhile to wrap my head around is that the data types for "i" and "j" are NOT the same. The data type for "i" is an array. The data type for "j" are the elements (usually numbers with these coding challenges) inside the arrays. You can't see that in an open grid structure. They all just look like numbers.

I hope this helps a little? It's definitely helped me solidify my own understanding of 2-Dimensional arrays, so thanks for letting me put it all down somewhere. :)

Best of luck!

Latest comments (0)