Tutorials Books Videos Forums

Change the theme! Search!
Rambo ftw!

Customize Theme


Color

Background


Done

Two-Dimensional (2D) Arrays in JavaScript

by kirupa   |   filed under Arrays

Learn how to create, access, and manipulate 2D arrays in JavaScript. Discover practical examples, visualization techniques, and modern ES6 approaches for working with multi-dimensional data.

When we think of arrays and the kind of data they store, we commonly think of them as storing a single line of elements:

This is great for many situations where we are storing a sequence of values such as entries in a todo list, country names, months in a year, a grocery list, and a whole lot more.

Now, what if the data we want to store is something more complex? What if we want to store data that is not a single sequence but is instead...multi-dimensional? A common example of something multi-dimensional is data in a table:

Our table has data stored in rows, and it has data stored in columns. An array designed to store a single sequence of values won’t cut it here. We will need something more elaborate. What we will need is the two-dimensional (or 2D) array, and we’re going to learn all about it in the following sections.

Onwards!

Kirupa's book on Arrays

The Perfect Book to Learn About Arrays

To kick your array skills into the stratosphere, everything you need to be an arrays expert is available in this book.

BUY ON AMAZON

Two-Dimensional Arrays 101

A two-dimensional array sounds all fancy and new, but it really isn’t. It is nothing more than an array that is made up of other arrays. It is not a new data structure or anything like that - at least not in JavaScript. The thing to keep in mind is this: If you know how to work with regular single arrays, two-dimensional arrays are familiar territory. Let me break it down for you.

Creating a 2D Array Manually

Let’s say we want to store the data from the table we saw earlier in the introduction. In that table, we have our data stored across 6 columns and 7 rows:

If we treat each row as an array and each column of data as an entry in that array, we can represent all of the data in this table as follows:

const salesData = [
  ["", "B", "C", "D", "E", "F"],
  [1, "D-01X", 68, 74, 60, 202],
  [2, "FR-0B1", 97, 76, 88, 261],
  [3, "P-034", 27, 49, 32, 108],
  [4, "P-105", 46, 44, 67, 157],
  [5, "W-11", 75, 68, 87, 230],
  [6, "W-24", 74, 52, 62, 188]
];

What we have here is a two-dimensional array called salesData. The contents of this array are...other arrays, and note how the values from our table are fully captured. The values are just array entries.

Accessing Values from a 2D Array

Think of a 2d array as a grid. Each cell in this grid has an x and y position. Now, instead of thinking about positions in terms of geographical coordinates we think of them in terms of index positions:

Given we have our array setup, the first index position would refer to the row, and the second index position would refer to the column. If we wanted to access the data in Row 1 and Column E, we use the following syntax:

salesData[1][4] // 60

In this example, salesData[1] indicates that we are looking at the 2nd row of data:

The [4] in salesData[1][4] specifies that, in the 2nd row of data, we are looking at the fifth column:

When we put all of this together, we see that salesData[1][4] refers to the 60 value. We can use a similar approach for getting at any other value in our table. Pretty nifty, right?

Note: Row-centric vs. Column-Centric

There is an important detail to note, and that has to do with how we represent our columns and rows. In our salesData array, we are row-centric where each row is represented as an array. The column is a value in the row.

If we flip things around and go column-centric instead, our columns would be represented as an array. The row would be a value in the column. In a column-centric world, our salesData array would look as follows:

const salesData = [
  ['', 1, 2, 3, 4, 5, 6],
  ['B', 'D-01X', 'FR-0B1', 'P-034', 'P-105', 'W-11', 'W-24'],
  ['C', 68, 97, 27, 46, 75, 74],
  ['D', 74, 76, 49, 44, 68, 52],
  ['E', 60, 88, 32, 67, 87, 62],
  ['F', 202, 261, 108, 157, 230, 188]
];

If we had to access the same 60 value from earlier, we will reference the index positions in reverse where instead of it being salesData[1][4] it would be salesData[4][1]. When working with 2d arrays, double check to see if the data is represented as a row-centric or column-centric arrangement.

 

Creating a 2D Array Programmatically

In many situations, we won’t be creating a 2D Array manually by defining all the individual rows and columns. When representing large amounts of data or representing dynamic data, it is more likely for us to generate a 2D array programmatically. To create a 2D array programmatically, we have two approaches we can take.

Old-school For Loop Approach

One approach is one where we use nested for loops to create the rows and columns:

function create2DArray(rows, cols, fillValue) {
  // Initialize an empty array that will become our 2D array
  const arr = [];
  
  // Outer loop: creates each row
  for (let i = 0; i < rows; i++) {
    // Initialize an empty array for this row
    arr[i] = [];
    
    // Inner loop: fills each column in the current row
    for (let j = 0; j < cols; j++) {
      // Set the value at the current position to the fill value
      arr[i][j] = fillValue;
    }
  }
  
  // Return the completed 2D array
  return arr;
}

// Create a 2D array made up of 3 rows, 4 columns, 
// and a default value of 0
const my2DArray = create2DArray(3, 4, 0);

// Log the entire 2D array to the console
console.log(my2DArray);

Here we have a create2dArray function that creates a 2D array based on the number of rows and columns we specify. We also specify the default value each cell will store. The end result of our code here is a 3x4 array with each cell having a value of 0.

Modern and Functional ES6 Approach

The other approach is much more compact and involves functional methods like Map:

function create2DArray(rows, cols, fillValue) {
  return Array(rows)  // Create an array with 'rows' number of empty slots
    .fill()           // Fill the empty slots with undefined
    .map(() =>        // Transform each slot into a new array
      Array(cols)     // Create an inner array with 'cols' number of empty slots
        .fill(fillValue)  // Fill the inner array with the specified fillValue
    );
}

// Create a 2D array made up of 3 rows, 4 columns, 
// and a default value of 0
const my2DArray = create2DArray(3, 4, 0);

// Log the entire 2D array to the console
console.log(myArray);

Our create2dArray function in this case takes up all of one line, but it is expanded into multiple lines to display the comments. Without comments, this function would indeed appear in a single line:

function create2DArray(rows, cols, fillValue) {
  return Array(rows).fill().map(() => Array(cols).fill(fillValue));
}

Anyhoo, when we call this function and provide the number of rows, columns, and default cell value, we still get back a multi-dimensional 2D array.

Visualizing 2d Arrays with console.table

Before we wrap things up, let’s talk about a cool tip for being able to visualize our 2d arrays. This trick involves using console.table instead of console.log. Going back to our example from earlier, let’s say we decide to visualize our salesData on our browser developer tools console:

const salesData = [
  ["", "B", "C", "D", "E", "F"],
  [1, "D-01X", 68, 74, 60, 202],
  [2, "FR-0B1", 97, 76, 88, 261],
  [3, "P-034", 27, 49, 32, 108],
  [4, "P-105", 46, 44, 67, 157],
  [5, "W-11", 75, 68, 87, 230],
  [6, "W-24", 74, 52, 62, 188]
];

If we used console.log to print these values, what we’ll see will look as follows:

We’ll see a list of array values that, when expanded, will help us see the individual items in each row. This isn’t bad, but there is a better way.

If we instead use console.table, the output will look as follows:

Notice, in this view, we see our 2d array represented exactly as a table. The rows, the columns, their values, and their respective index positions are all clearly visible. I don’t know about you, but console.table is much MUCH nicer than console.log when it comes to displaying multi-dimensional data.

Wrapping Things Up

Now that we’ve learned a whole lot about two-dimensional arrays and how to work with them, let’s quickly review the important details:

  1. Structure: It consists of an array of arrays, where each inner array typically represents a row.
  2. Dimensions: It has two indices to access elements - one for the row and one for the column.
  3. Layout: Data is arranged in a tabular format, similar to a grid or matrix or table.
  4. Memory: Elements are stored in contiguous memory locations
  5. Access: Elements are accessed using two indices, like array[row][column]

With this overview out of the way, its time for us to go off in our merry paths and put all of this 2d array knowledge to good use. One place we see 2d arrays used a whole lot is in our Cluster Growth Animation deconstruction, so go check that if you want more 2d array goodness.

Just a final word before we wrap up. If you have a question and/or want to be part of a friendly, collaborative community of over 220k other developers like yourself, post on the forums for a quick response!

Kirupa's signature!

The KIRUPA Newsletter

Thought provoking content that lives at the intersection of design 🎨, development 🤖, and business 💰 - delivered weekly to over a bazillion subscribers!

SUBSCRIBE NOW

Creating engaging and entertaining content for designers and developers since 1998.

Follow:

Popular

Loose Ends

:: Copyright KIRUPA 2024 //--