Online Compiler logoOnline Compiler

JavaScript Tutorial

JavaScript Nested Loops

Learn nested loops for multi-dimensional data. Master matrices, patterns, and complex iteration.

Why this matters

Nested loops are essential for working with multi-dimensional data structures like matrices, tables, and complex objects. They're fundamental for games, data processing, and algorithmic problems.

What are Nested Loops?

Nested loops are loops inside other loops. The inner loop runs completely for each iteration of the outer loop.

They're essential for working with multi-dimensional data structures like matrices, tables, and complex objects.

Basic Nested for Loops

for (let i = 0; i < 3; i++) {
  console.log(`Outer loop: ${i}`);

  for (let j = 0; j < 2; j++) {
    console.log(`  Inner loop: ${j}`);
  }
}

// Output:
// Outer loop: 0
//   Inner loop: 0
//   Inner loop: 1
// Outer loop: 1
//   Inner loop: 0
//   Inner loop: 1
// Outer loop: 2
//   Inner loop: 0
//   Inner loop: 1

Inner loop completes all iterations for each outer loop iteration.

Working with 2D Arrays

Nested loops are perfect for iterating through two-dimensional arrays (matrices).

Iterating 2D Array

const matrix = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
];

for (let i = 0; i < matrix.length; i++) {
  for (let j = 0; j < matrix[i].length; j++) {
    console.log(`matrix[${i}][${j}] = ${matrix[i][j]}`);
  }
}

// Output:
// matrix[0][0] = 1
// matrix[0][1] = 2
// matrix[0][2] = 3
// matrix[1][0] = 4
// matrix[1][1] = 5
// matrix[1][2] = 6
// matrix[2][0] = 7
// matrix[2][1] = 8
// matrix[2][2] = 9

Access each element in a 2D array using nested loops.

Matrix Operations

function printMatrix(matrix) {
  for (let row of matrix) {
    let rowString = '';
    for (let cell of row) {
      rowString += cell + ' ';
    }
    console.log(rowString.trim());
  }
}

const gameBoard = [
  ['X', 'O', 'X'],
  ['O', 'X', 'O'],
  ['X', 'O', 'X']
];

printMatrix(gameBoard);

// Output:
// X O X
// O X O
// X O X

Nested loops help format and display matrix data.

Different Loop Type Combinations

You can mix different types of loops in nested structures.

for...of with for Loop

const students = [
  { name: 'Alice', grades: [85, 92, 78] },
  { name: 'Bob', grades: [90, 88, 95] },
  { name: 'Charlie', grades: [75, 82, 88] }
];

for (const student of students) {
  console.log(`${student.name}'s grades:`);

  for (let i = 0; i < student.grades.length; i++) {
    console.log(`  Test ${i + 1}: ${student.grades[i]}`);
  }
}

Combine for...of for objects with for loops for array indices.

while with for Loop

let rows = 3;
let cols = 4;
let counter = 1;

let i = 0;
while (i < rows) {
  let row = '';

  for (let j = 0; j < cols; j++) {
    row += counter + ' ';
    counter++;
  }

  console.log(row.trim());
  i++;
}

// Output:
// 1 2 3 4
// 5 6 7 8
// 9 10 11 12

Mix while loops with for loops for different control patterns.

Common Use Cases

Nested loops solve many real-world problems involving multi-dimensional data.

Finding Maximum in 2D Array

function findMaxInMatrix(matrix) {
  let max = matrix[0][0];

  for (let row of matrix) {
    for (let value of row) {
      if (value > max) {
        max = value;
      }
    }
  }

  return max;
}

const scores = [
  [85, 92, 78, 90],
  [88, 95, 82, 87],
  [90, 88, 93, 85]
];

console.log("Highest score:", findMaxInMatrix(scores)); // 95

Search through all elements in a 2D array to find the maximum value.

Matrix Transposition

function transposeMatrix(matrix) {
  const rows = matrix.length;
  const cols = matrix[0].length;
  const transposed = [];

  for (let j = 0; j < cols; j++) {
    transposed[j] = [];
    for (let i = 0; i < rows; i++) {
      transposed[j][i] = matrix[i][j];
    }
  }

  return transposed;
}

const original = [
  [1, 2, 3],
  [4, 5, 6]
];

const transposed = transposeMatrix(original);
console.log("Original:", original);
console.log("Transposed:", transposed);

// Output:
// Original: [[1, 2, 3], [4, 5, 6]]
// Transposed: [[1, 4], [2, 5], [3, 6]]

Swap rows and columns using nested loops.

Pattern Generation

function printPattern(size) {
  for (let i = 1; i <= size; i++) {
    let row = '';

    for (let j = 1; j <= i; j++) {
      row += '* ';
    }

    console.log(row.trim());
  }
}

printPattern(5);

// Output:
// *
// * *
// * * *
// * * * *
// * * * * *

Generate patterns using nested loops with different iteration ranges.

Multiplication Table

function printMultiplicationTable(size) {
  for (let i = 1; i <= size; i++) {
    let row = '';

    for (let j = 1; j <= size; j++) {
      row += (i * j) + '	';
    }

    console.log(row);
  }
}

printMultiplicationTable(5);

// Output:
// 1	2	3	4	5
// 2	4	6	8	10
// 3	6	9	12	15
// 4	8	12	16	20
// 5	10	15	20	25

Generate multiplication tables using nested loops.

Performance Considerations

Nested loops can have performance implications, especially with large datasets.

Time Complexity

// O(n²) - quadratic time complexity
function processLargeMatrix(matrix) {
  const start = Date.now();

  for (let i = 0; i < matrix.length; i++) {
    for (let j = 0; j < matrix[i].length; j++) {
      // Process each element
      matrix[i][j] *= 2;
    }
  }

  const end = Date.now();
  console.log(`Processing took: ${end - start}ms`);
}

// For a 1000x1000 matrix: 1,000,000 operations!
// For a 2000x2000 matrix: 4,000,000 operations!

Nested loops create exponential time complexity - be careful with large datasets.

Early Termination

function findInMatrix(matrix, target) {
  for (let i = 0; i < matrix.length; i++) {
    for (let j = 0; j < matrix[i].length; j++) {
      if (matrix[i][j] === target) {
        return [i, j]; // Found it! Exit early
      }
    }
  }
  return null;
}

const largeMatrix = Array(1000).fill().map(() =>
  Array(1000).fill().map(() => Math.floor(Math.random() * 1000))
);

console.log(findInMatrix(largeMatrix, 42)); // Fast even with 1M elements

Use early returns to avoid unnecessary iterations in nested loops.

Control Flow in Nested Loops

break and continue behave differently in nested loops.

break in Nested Loops

// break only exits inner loop
for (let i = 0; i < 3; i++) {
  console.log(`Outer: ${i}`);

  for (let j = 0; j < 3; j++) {
    if (j === 2) {
      break; // Only exits inner loop
    }
    console.log(`  Inner: ${j}`);
  }
}

// Output:
// Outer: 0
//   Inner: 0
//   Inner: 1
// Outer: 1
//   Inner: 0
//   Inner: 1
// Outer: 2
//   Inner: 0
//   Inner: 1

break only exits the innermost loop, outer loop continues.

Labeled break

outerLoop: for (let i = 0; i < 3; i++) {
  console.log(`Outer: ${i}`);

  for (let j = 0; j < 3; j++) {
    if (i === 1 && j === 1) {
      break outerLoop; // Exit both loops
    }
    console.log(`  Inner: ${j}`);
  }
}

// Output:
// Outer: 0
//   Inner: 0
//   Inner: 1
//   Inner: 2
// Outer: 1
//   Inner: 0
//   Inner: 1

Use labeled breaks to exit multiple nested loops.

Best Practices

Write efficient and readable nested loop code.

  • Be aware of time complexity (O(n²) for 2D, O(n³) for 3D)
  • Use meaningful variable names (row, col instead of i, j)
  • Consider early termination to improve performance
  • Extract complex nested logic into separate functions
  • Use labels sparingly for breaking out of multiple loops
  • Test with small datasets first to verify logic
  • Consider alternative data structures for better performance

Common Mistakes

  • Incorrect loop bounds: Use matrix.length for rows and matrix[i].length for columns in 2D arrays.
  • Forgetting break only exits inner loop: Use labeled breaks or restructure code when you need to exit multiple loops.
  • Poor performance with large datasets: Consider if nested loops are necessary or if there's a more efficient algorithm.

Frequently Asked Questions

How many levels deep can loops be nested?

There's no strict limit, but more than 3 levels becomes hard to read and maintain.

What's the time complexity of nested loops?

Two nested loops are O(n²), three nested loops are O(n³), etc.

Can I mix different loop types when nesting?

Yes, you can nest for, while, do...while, and for...of loops in any combination.