Programming
Arrays
Two-Dimensional Arrays
Data Structures
Coding Tutorial

How to define a two-dimensional array?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

A two-dimensional array stores values in rows and columns, which makes it a natural fit for tables, grids, game boards, and matrix-style data. In most languages, a 2D array is really an array whose elements are themselves arrays, so understanding shape and indexing matters as much as syntax.

Declaring the Array

The basic idea is to choose how many rows and columns you need, then allocate storage for both dimensions. In languages with fixed-size arrays, you often declare the full shape up front. In languages with dynamic lists, each row can be created separately.

Here is a Java example:

java
1public class MatrixDemo {
2    public static void main(String[] args) {
3        int[][] matrix = new int[3][4];
4
5        matrix[0][0] = 10;
6        matrix[1][2] = 25;
7        matrix[2][3] = 99;
8
9        System.out.println(matrix[1][2]);
10    }
11}

matrix[3][4] means three rows and four columns. The first index selects the row, and the second index selects the column inside that row.

In Python, the common equivalent is a list of lists:

python
1matrix = [
2    [1, 2, 3],
3    [4, 5, 6],
4    [7, 8, 9],
5]
6
7print(matrix[2][1])  # 8

The syntax is different, but the mental model is the same.

Initializing with Values

If you already know the contents, literal initialization is clearer than creating an empty grid and filling it later. That is especially true for examples, lookup tables, or test data.

cpp
1#include <iostream>
2
3int main() {
4    int board[2][3] = {
5        {1, 2, 3},
6        {4, 5, 6}
7    };
8
9    std::cout << board[0][2] << "\n";
10    return 0;
11}

This style makes the shape visible at a glance. It also reduces mistakes when the grid is small enough to read directly.

When you need a default value everywhere, create each row carefully. In JavaScript, this is a common safe pattern:

javascript
1const rows = 3;
2const cols = 4;
3
4const grid = Array.from(
5  { length: rows },
6  () => Array(cols).fill(0)
7);
8
9grid[0][1] = 7;
10console.log(grid);

The callback creates a fresh inner array for every row. That detail matters because reusing the same inner array produces surprising shared updates.

Traversing Rows and Columns

Once the array exists, the next task is usually traversal. A nested loop is the standard solution because you need to visit each row and then each column within that row.

java
1public class SumMatrix {
2    public static void main(String[] args) {
3        int[][] values = {
4            {2, 4, 6},
5            {1, 3, 5}
6        };
7
8        int sum = 0;
9
10        for (int row = 0; row < values.length; row++) {
11            for (int col = 0; col < values[row].length; col++) {
12                sum += values[row][col];
13            }
14        }
15
16        System.out.println(sum);
17    }
18}

Notice the use of values[row].length instead of assuming every row has the same length. That makes the code work even when the structure is jagged.

Rectangular Versus Jagged Shapes

Not every 2D array is a perfect rectangle. In Java and JavaScript, each row can have a different length, which creates a jagged array. That is useful for triangular data, sparse layouts, or inputs where each row naturally holds a different number of items.

java
1public class JaggedArrayDemo {
2    public static void main(String[] args) {
3        int[][] triangle = {
4            {1},
5            {2, 3},
6            {4, 5, 6}
7        };
8
9        for (int[] row : triangle) {
10            for (int value : row) {
11                System.out.print(value + " ");
12            }
13            System.out.println();
14        }
15    }
16}

If your algorithm expects a rectangular matrix, validate the row lengths first. Otherwise, an index that exists in one row may fail in another.

Common Pitfalls

One frequent mistake is swapping the meaning of the indices. matrix[row][col] and matrix[col][row] are not interchangeable, and the bug can remain hidden if the matrix is square.

Another common issue is using the same inner array for every row in JavaScript. Code like new Array(3).fill(new Array(4).fill(0)) creates shared rows, so updating one cell updates the same column in every row.

Developers also get tripped up by jagged structures. In Java, array.length gives the number of rows, but array[row].length gives the number of columns in that specific row. Using the wrong length causes out-of-bounds errors.

Finally, do not confuse a list of lists with a mathematically dense matrix. They may look similar, but memory layout, performance, and supported operations depend on the language and library you use.

Summary

  • A two-dimensional array represents data with both row and column indices.
  • In many languages, a 2D array is implemented as an array of arrays.
  • Use literal initialization when the starting values are already known.
  • Traverse a 2D array with nested loops, and use the current row length when needed.
  • Be careful with jagged arrays and shared inner arrays, especially in JavaScript.

Course illustration
Course illustration

All Rights Reserved.