2D arrays vs. Nested arrays
Published: 2022-02-11 16:36:04

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.

```javascript
let myArray = [[1,2,3],[4,5,6]]
```
If we were to access an element in that outer array, we would call it via single bracket notation and the appropriate index.
```javascript
myArray[1]     // [4,5,6]
```
To call an element inside one of the inner arrays, we would need to add a second bracket.
```javascript
myArray[1][2]     // 6
```
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.
```javascript
let longArray = [[a,f,x,d],[q,l],[m,c,u,t,i],[w],[b,g,o]]
```
(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.
```javascript
1  6  3  4
2  8  5  0
9  2  7  7
3  5  0  2
```
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.
```javascript
[
  [1, 6, 3, 4],
  [2, 8, 5, 0],
  [9, 2, 7, 7],
  [3, 5, 0, 2]
]
```
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.
```javascript
[
  [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]]
```
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.
```javascript
for(let i = 0; i < myArray.length; i++){
     for(let j = 0; j < myArray.length; j++{
          //your code here
     }
}
```
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.
```javascript
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
```
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...
```javascript
for(let i = 0; i < myArray.length; i++){
     for(let j = myArray.length; j >=0; j--{
          //your code here
     }
}
```
... and the corresponding results would look like this.
```javascript
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
```
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?
```javascript
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
```
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...
```javascript
[
  [1, 6, 3, 4],
  [2, 8, 5, 0],
  [9, 2, 7, 7],
  [3, 5, 0, 2]
]
```
...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.
```javascript
for(let i = 0; i < Arr.length; i++){
     for(let j = 0; j < Arr.length; j++{
          //your code here
     }
}
```
Remember that the "i" in this algorithm represents the indices of the OUTER array.  Those are the rows.
```javascript
// 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]
     ]
```
The columns, the indices of the INNER arrays, are the "j".
```javascript
//                 [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]    
          ]
```
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!