One loop is powerful. Two loops working together unlock entire new dimensions — multiplication tables, star patterns, grid data, and complex algorithms. Master nested loops and you can solve problems that single loops cannot touch.
Day 24 / 180
Beginner Phase
🕐15 min read
💻7 code examples
🎯3 practice tasks
📝5 quiz questions
Here is a problem that requires nested loops:
Why one loop isn't enough
// Imagine you have 3 students, each with 4 test scoreslet scores = [
[85, 90, 78, 92], // Student 1
[88, 76, 95, 89], // Student 2
[91, 84, 87, 93] // Student 3
];
// ❌ One loop cannot handle this — you need to loop through students AND scoresfor (let i = 0; i < scores.length; i++) {
// How do you access each score? You need another loop!
}
// ✅ Two loops (nested) — perfect for the jobfor (let student = 0; student < scores.length; student++) {
for (let test = 0; test < scores[student].length; test++) {
console.log(`Student ${student + 1}, Test ${test + 1}: ${scores[student][test]}`);
}
}
Nested loops are exactly what they sound like — a loop inside another loop. The inner loop completes all its iterations for each single iteration of the outer loop. If the outer loop runs 5 times and the inner loop runs 10 times, the inner loop's code executes 50 times total (5 × 10). This pattern is essential for working with grids, matrices, multiplication tables, star patterns, and any data that has multiple dimensions. Today, I'll show you how to master nested loops and avoid the common performance pitfalls that come with them.
1. The Problem — When One Loop Is Not Enough
Many real-world problems involve data that has multiple dimensions. Think of a chessboard — it has 8 rows, and each row has 8 columns. To process every square on the board, you need to visit each row, and for each row, visit each column. This is exactly what nested loops do: an outer loop handles the rows, and an inner loop handles the columns.
Here's the key concept: for each iteration of the outer loop, the inner loop runs to completion. This creates a total iteration count of outer × inner. If you're working with a 10×10 grid, that's 100 total iterations. If you have a 100×100 grid, that's 10,000 iterations. Understanding this multiplication effect is crucial because it directly impacts performance.
Understanding the Multiplication Effect
// Outer loop runs 3 times, inner loop runs 4 times// Total executions = 3 × 4 = 12for (let i = 1; i <= 3; i++) { // Outer loop: i = 1, 2, 3
console.log(`Outer loop: i = ${i}`);
for (let j = 1; j <= 4; j++) { // Inner loop: j = 1, 2, 3, 4 for EACH i
console.log(` Inner loop: j = ${j}`);
}
}
/* Output shows the pattern:
Outer loop: i = 1
Inner loop: j = 1
Inner loop: j = 2
Inner loop: j = 3
Inner loop: j = 4
Outer loop: i = 2
Inner loop: j = 1
Inner loop: j = 2
Inner loop: j = 3
Inner loop: j = 4
Outer loop: i = 3
Inner loop: j = 1
Inner loop: j = 2
Inner loop: j = 3
Inner loop: j = 4
*/// Notice: For each i value (1, 2, 3), j runs through all 4 values (1, 2, 3, 4)// That's why total iterations = 3 × 4 = 12
💡 The mental model: Think of a clock's minute and hour hands. The hour hand moves slowly (outer loop), and for each hour, the minute hand completes a full cycle (inner loop). When the hour hand moves from 1 to 2, the minute hand goes all the way around 60 times. That's nested iteration!
2. Nested Loops — Syntax and Basic Examples
Creating a nested loop is simple — just write one loop inside another. Use different variable names for each level (typically i for outer, j for inner, k for third level). The inner loop can use the outer loop's variable in its condition or body, which is what makes nested loops so powerful.
Basic Nested Loop Examples
// Example 1: Simple counter — outer counts rows, inner counts columnsfor (let row = 1; row <= 3; row++) {
let line = "";
for (let col = 1; col <= 4; col++) {
line += `(${row},${col}) `;
}
console.log(line);
}
// Output:// (1,1) (1,2) (1,3) (1,4)// (2,1) (2,2) (2,3) (2,4)// (3,1) (3,2) (3,3) (3,4)// Example 2: Inner loop depends on outer loop (triangular pattern)for (let i = 1; i <= 5; i++) {
let stars = "";
for (let j = 1; j <= i; j++) { // Inner loop runs 'i' times
stars += "⭐";
}
console.log(stars);
}
// Output:// ⭐// ⭐⭐// ⭐⭐⭐// ⭐⭐⭐⭐// ⭐⭐⭐⭐⭐// Example 3: Multiplication table (5×5)
console.log("Multiplication Table (1-5):");
for (let i = 1; i <= 5; i++) {
let row = "";
for (let j = 1; j <= 5; j++) {
let product = i * j;
row += (product.toString().padStart(4));
}
console.log(row);
}
// Output: A 5×5 multiplication table
📝 QUIZ 1 & 2Test Your Understanding
Question 1: If an outer loop runs 10 times and an inner loop runs 5 times, how many times does the inner loop's code execute?
Question 2: What is the correct variable naming convention for nested loops?
3. Creating Patterns with Nested Loops
One of the most satisfying uses of nested loops is creating visual patterns. By controlling when the inner loop runs and what it outputs, you can create triangles, diamonds, pyramids, and other shapes. The key is understanding how the inner loop's boundary relates to the outer loop's current value.
Common Nested Loop Patterns
// Pattern 1: Right-aligned triangle (spaces + stars)for (let i = 1; i <= 5; i++) {
let line = "";
// Add spaces (5 - i spaces)for (let s = 1; s <= 5 - i; s++) {
line += " ";
}
// Add stars (i stars)for (let j = 1; j <= i; j++) {
line += "⭐";
}
console.log(line);
}
// Pattern 2: Pyramidlet n = 5;
for (let i = 1; i <= n; i++) {
let line = "";
// Spaces (decreasing)for (let s = 1; s <= n - i; s++) {
line += " ";
}
// Stars (increasing by 2)for (let j = 1; j <= 2 * i - 1; j++) {
line += "⭐";
}
console.log(line);
}
// Output: A beautiful star pyramid!// Pattern 3: Number trianglefor (let i = 1; i <= 5; i++) {
let line = "";
for (let j = 1; j <= i; j++) {
line += j + " ";
}
console.log(line);
}
// Output:// 1// 1 2// 1 2 3// 1 2 3 4// 1 2 3 4 5// Pattern 4: Floyd's Triangle (consecutive numbers)let num = 1;
for (let i = 1; i <= 5; i++) {
let line = "";
for (let j = 1; j <= i; j++) {
line += num + " ";
num++;
}
console.log(line);
}
// Output:// 1// 2 3// 4 5 6// 7 8 9 10// 11 12 13 14 15
4. Working with 2D Arrays (Matrices)
A 2D array is simply an array where each element is another array. Think of it as a table with rows and columns. Nested loops are the natural way to process 2D arrays — the outer loop iterates through rows, and the inner loop iterates through columns in that row. This pattern is used everywhere: game boards, image pixels, spreadsheet data, and more.
2D Array Operations
// Creating a 2D array (3 rows, 4 columns)let matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
];
// Accessing elements: matrix[row][column]
console.log(matrix[0][2]); // 3 (row 0, column 2)
console.log(matrix[2][1]); // 10 (row 2, column 1)// Operation 1: Print entire matrixfor (let row = 0; row < matrix.length; row++) {
let line = "";
for (let col = 0; col < matrix[row].length; col++) {
line += matrix[row][col] + "\t";
}
console.log(line);
}
// Operation 2: Sum of all elementslet total = 0;
for (let i = 0; i < matrix.length; i++) {
for (let j = 0; j < matrix[i].length; j++) {
total += matrix[i][j];
}
}
console.log(`Sum of all elements: ${total}`); // 78// Operation 3: Find maximum valuelet max = matrix[0][0];
for (let i = 0; i < matrix.length; i++) {
for (let j = 0; j < matrix[i].length; j++) {
if (matrix[i][j] > max) max = matrix[i][j];
}
}
console.log(`Maximum value: ${max}`); // 12// Operation 4: Create a 2D array dynamicallylet rows = 4;
let cols = 5;
let dynamicMatrix = [];
for (let i = 0; i < rows; i++) {
dynamicMatrix[i] = []; // Create new rowfor (let j = 0; j < cols; j++) {
dynamicMatrix[i][j] = i * cols + j + 1;
}
}
console.log("Dynamic 4×5 matrix created!");
📝 QUIZ 3 & 4Test Your Understanding
Question 3: Given let matrix = [[1,2],[3,4],[5,6]], what does matrix[2][0] return?
Question 4: What is the total number of iterations if you have a 3×4 2D array?
5. Common Mistakes to Avoid
Mistakes & Fixes
// ❌ MISTAKE 1: Using the same variable name for both loopsfor (let i = 0; i < 3; i++) {
for (let i = 0; i < 4; i++) { // ❌ Same variable name 'i'
console.log(i); // Confusing! Which 'i' is this?
}
}
// ✅ FIX: Use different names (i, j, k)for (let i = 0; i < 3; i++) {
for (let j = 0; j < 4; j++) {
console.log(`i=${i}, j=${j}`);
}
}
// ❌ MISTAKE 2: Swapping row and column limits (index error)let matrix = [[1,2],[3,4]];
for (let i = 0; i < matrix[0].length; i++) { // ❌ Using column count for rowsfor (let j = 0; j < matrix.length; j++) { // ❌ Using row count for columns
console.log(matrix[i][j]); // May cause undefined or crash
}
}
// ✅ FIX: Rows = matrix.length, Columns = matrix[i].lengthfor (let i = 0; i < matrix.length; i++) {
for (let j = 0; j < matrix[i].length; j++) {
console.log(matrix[i][j]);
}
}
// ❌ MISTAKE 3: Off-by-one in triangular patternsfor (let i = 0; i <= 5; i++) { // Should be i < 5 or i <= 4for (let j = 0; j <= i; j++) { // This runs i+1 times// May create extra row/column
}
}
// ✅ FIX: Be precise with boundariesfor (let i = 0; i < 5; i++) {
for (let j = 0; j <= i; j++) { // This gives i+1 iterations, correct for triangle// Works as expected
}
}
// ❌ MISTAKE 4: Performance trap — nested loops with large rangesfor (let i = 0; i < 10000; i++) {
for (let j = 0; j < 10000; j++) {
// This runs 100 MILLION times (10000 × 10000)!// Will freeze your browser!
}
}
⚠️ Performance Warning: The Multiplication Effect
Remember: nested loops multiply iteration counts. A 1000×1000 nested loop = 1,000,000 operations. A 10,000×10,000 nested loop = 100,000,000 operations (will likely freeze your browser). Always consider whether you can reduce the size of your data or optimize your algorithm before running large nested loops.
6. Best Practices — Using Nested Loops Wisely
🎯 Use Meaningful Variable Names
Instead of generic i and j, use descriptive names like row and col for matrices, or student and test for grade data. Your future self will thank you.
📊 Understand Your Complexity
Before writing nested loops, calculate the total iterations (outer × inner). If it's more than a few hundred thousand, consider whether you really need to process all that data, or if you can filter or optimize first.
🔄 Break Early When Possible
If you're searching through a 2D array and find what you need, use break to exit the inner loop, and consider using a labeled break to exit both loops. This can dramatically improve performance.
📦 Extract Inner Loops to Functions
If your inner loop is complex, consider extracting it into a separate function. This makes your code more readable and testable.
7. Try It Yourself — Star Pattern Generator
Use this playground to generate different star patterns by adjusting the number of rows. See how nested loops create the patterns in real time.
✏️ Star Pattern Generator
HTML
JAVASCRIPT
LIVE PREVIEW
💡 Adjust rows and pattern type to see nested loops in action!
8. Practice Tasks
Task 1 — Easy: Multiplication Table
Write nested loops to generate a 10×10 multiplication table. The output should show rows 1-10 and columns 1-10 with the product of row × column. Format it neatly so columns align.
Task 2 — Medium: Matrix Sum
Given a 3×3 matrix ([[1,2,3],[4,5,6],[7,8,9]]), write nested loops to calculate: (a) the sum of all elements, (b) the sum of each row, and (c) the sum of each column.
Task 3 — Hard: Find Duplicates in 2D Array
Write a function findDuplicates(matrix) that uses nested loops to find any duplicate values in a 2D array. Return an array of duplicate values found. Test with: [[1,2,3],[4,2,5],[6,7,1]] (should return [1,2]).
📝 FINAL QUIZTest Your Mastery
Question 5: If you have a 2D array with 5 rows and 6 columns, how many total iterations will a nested loop (outer over rows, inner over columns) perform?