Programming Fundamentals

Loops and Iteration

3 min read
Focus: PROGRAMMING-FUNDAMENTALS

TL;DR — Quick Summary

  • Prefer array methods (map, filter, reduce) over for loops for array transformations — they're declarative and composable.
  • Use for...of for clean iteration when you need the values but not array methods.
  • find returns the first match; filter returns all matches; some/every return booleans.
  • Always ensure a while loop can exit — an infinite loop crashes your program.

Lesson Overview

Loops are one of programming's most powerful constructs — they let you run the same logic thousands of times without writing it thousands of times. Every data processing task, every list rendering, every animation update uses loops in some form.

JavaScript has traditional loops (for, while, do...while, for...of, for...in) and modern array methods (forEach, map, filter, reduce, find, some, every). Understanding when to use each is a key skill.

A critical rule: always ensure your loop can exit. An infinite loop will freeze the browser or crash a server.

Conceptual Deep Dive

Traditional loops:

  • for: use when you know the iteration count, need the index, or need precise control
  • while: use when the exit condition depends on runtime state (user input, data streaming)
  • do...while: like while but always runs at least once (menus, input validation)
  • for...of: clean syntax to iterate over any iterable (arrays, strings, sets, maps)
  • for...in: iterates over object keys — avoid for arrays

Array methods (prefer these for arrays):

  • forEach: run a function on each item — no return value
  • map: transform each item → returns a new array of the same length
  • filter: keep items matching a condition → returns a new (possibly shorter) array
  • reduce: accumulate all items into a single value (sum, object, etc.)
  • find: returns the first item matching a condition (or undefined)
  • findIndex: returns the index of the first match (or -1)
  • some: returns true if at least one item matches
  • every: returns true if all items match
  • flat / flatMap: flatten nested arrays

Implementation Lab

Traditional Loops
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// for loop — iterate a known number of times
for (let i = 0; i < 5; i++) {
  console.log(`Step ${i + 1}`{i + 1}`);
}
 
// for...of — clean array iteration (no index needed)(no index needed)
const fruits = ['apple', 'banana', 'cherry'];
for (const fruit of fruits) {
  console.log(fruit.toUpperCase());
}
 
// for...of with index (using entries())(using entries())
for (const [index, fruit] of fruits.entries()) {
  console.log(`${index + 1}. ${fruit}`1}. ${fruit}`);
}
 
// while — repeat until condition is falsefalse
let attempts = 0;
let password = '';
while (password !== 'secret') {
  attempts++;
  password = prompt('Enter password:') ?? '';
  if (attempts >= 3) {
    console.log('Too many attempts. Account locked.'Account locked.');
    break;
  }
}
 
// do...while — always runs at least once
let input;
do {
  input = getUserInput();
} while (!isValid(input));
 
// break and continue
for (let i = 0; i < 10; i++) {
  if (i === 3) continue; // skip 3
  if (i === 7) break;    // stop at 7
  console.log(i); // 0 1 2 4 5 61 2 4 5 6
}
Modern Array Methods
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
const products = [
  { id: 1, name: 'Laptop',  price: 999,  inStock: true,  category: 'electronics' },
  { id: 2, name: 'T-Shirt'Shirt', price: 25,   inStock: true,  category: 'clothing' },
  { id: 3, name: 'Phone',   price: 699,  inStock: false, category: 'electronics' },
  { id: 4, name: 'Jeans',   price: 80,   inStock: true,  category: 'clothing' },
  { id: 5, name: 'Tablet',  price: 449,  inStock: true,  category: 'electronics' },
];
 
// map: transform → get names only
const names = products.map(p => p.name);
console.log(names); // ['Laptop', 'T-Shirt', 'Phone', 'Jeans', 'Tablet']'Laptop', 'T-Shirt'Shirt', 'Phone', 'Jeans', 'Tablet']
 
// filter: keep in-stock electronics
const available = products.filter(p => p.inStock && p.category === 'electronics');
console.log(available.map(p => p.name)); // ['Laptop', 'Tablet']'Laptop', 'Tablet']
 
// reduce: sum total inventory value
const totalValue = products
  .filter(p => p.inStock)
  .reduce((sum, p) => sum + p.price, 0);
console.log(`Total: $${totalValue}`{totalValue}`); // $1553
 
// find: get first item under $100
const budget = products.find(p => p.price < 100);
console.log(budget?.name); // 'T-Shirt'Shirt'
 
// some / every
const anyOutOfStock = products.some(p => !p.inStock);
console.log(anyOutOfStock); // true
 
const allElectronicsExpensive = products
  .filter(p => p.category === 'electronics')
  .every(p => p.price > 400);
console.log(allElectronicsExpensive); // true
 
// Chaining methods
const expensiveInStockNames = products
  .filter(p => p.inStock)
  .filter(p => p.price > 100)
  .map(p => p.name)
  .sort();
console.log(expensiveInStockNames); // ['Jeans' excluded, 'Laptop', 'Tablet']'Jeans' excluded, 'Laptop', 'Tablet']

Pro Tips — Senior Dev Insights

1

Chain array methods to build clean data pipelines: data.filter(...).map(...).sort() is readable and composable — much better than a loop with nested ifs.

2

reduce is the most powerful array method — it can implement any other method. Use it to build objects from arrays, flatten nested arrays, or group items by category.

3

Use for...of with break when you need to stop early — array methods can't break out of iteration, but some() stops on the first truthy result, which is a useful workaround.

Common Developer Pitfalls

!
Using forEach when you want to return a transformed array — forEach returns undefined. Use map instead.
!
Mutating the original array inside map or filter — these methods should be pure (no side effects). Create new values instead of modifying existing ones.
!
Using for...in on arrays — it iterates over all enumerable properties including any prototype additions, and the index is a string, not a number. Use for...of or indexed for for arrays.
!
Off-by-one errors in for loops — i <= arr.length will access an undefined element. Use i < arr.length.

Interview Mastery

for: best when you know the iteration count upfront or need precise index control. Structure: initialisation; condition; update. while: best when the exit condition depends on runtime events and you might not enter the loop at all. do-while: like while but always executes the body at least once before checking the condition — useful for input validation where you need at least one attempt. In practice, prefer for...of for arrays and array methods for transformations.

forEach: when you want to perform a side effect (log, update DOM) on each item — it returns undefined, never chain it. map: when you want to transform each item into something new — returns a new array of the same length. filter: when you want a subset of items matching a condition — returns a new (possibly shorter) array. reduce: when you want to combine all items into a single value (sum, count, object) — most flexible, can implement all others. find: when you want the first matching item. some/every: when you want a boolean about all items.

Nested loops have one loop inside another. The inner loop completes fully for each iteration of the outer loop. Time complexity is O(n²) or worse — use carefully with large datasets. Real-world examples: generating a grid (row × column), comparing every item to every other item, processing a 2D data structure (matrix, spreadsheet). Modern alternatives: Array.flat() for nested arrays, Object.entries() for objects, or restructuring data to avoid nesting. Always consider performance — nested loops with thousands of items can freeze the UI.

break immediately exits the entire loop — no more iterations occur. continue skips the current iteration and jumps to the next one. Example: in a loop processing payments, break if you hit a fatal error (stop everything), continue if you hit a skippable error (skip that payment, process the rest). In array methods, you can't use break/continue — use find() or some() which stop early on a match, or for...of with break.

Hands-on Lab Exercises

1
Process an array of transactions: use filter to find debits over $100, map to format them as strings, reduce to calculate the total.
2
Build a search function: given an array of users and a search query, return all users whose name includes the query (case-insensitive) using filter.
3
Find the first available product in a sorted list using find — then use findIndex to get its position.
4
Use every to validate a form: ensure all required fields are non-empty in one call.

Real-World Practice Scenarios

E-commerce cart: Use reduce to calculate cart total, map to apply a discount to each item, filter to remove out-of-stock items.
Data dashboard: Group an array of sales records by month using reduce into an object of { month: total }.
User search: Filter a user list by multiple criteria (name, role, active status) by chaining filter calls.
Game leaderboard: Use sort + map + slice to show the top 10 players with ranked positions.

Deepen Your Knowledge