Skip to content

Beginner · Strings, decisions and loops · topic 10 of 61 · 25 min

Loop patterns that solve real problems

Explanation

Most loop problems are one of a few patterns: the accumulator (sum or count), the search (find the first match and stop), the best-so-far (min or max), the builder (make a new array or string) and the nested loop (rows and columns). Learn the patterns and new problems become familiar.

Why learn patterns?

Beginners often stare at a blank editor. Experienced programmers recognise the shape of the problem first: "this is a count", "this is a search". Each shape has a standard loop. Here are the five you will use most.

1. The accumulator

An accumulator is a variable that collects a result as the loop goes: a running total or a count. Start it at the "empty" value (0 for sums, 0 for counts, '' for text) BEFORE the loop.

javascript
const bills = [450, 120, 980, 60];
let total = 0;
let bigBills = 0;
for (const b of bills) {
  total += b;
  if (b > 400) bigBills++;
}
console.log(total, bigBills); // 1610 2

Look for the first item that matches, and stop as soon as you find it. Keep a result variable that starts as "not found" (null or -1).

javascript
const pnrs = ['4521', '8890', '1234'];
let foundAt = -1;
for (let i = 0; i < pnrs.length; i++) {
  if (pnrs[i] === '8890') {
    foundAt = i;
    break;   // no need to look further
  }
}
console.log(foundAt); // 1

3. Best so far (min and max)

Start with the first item as the best, then compare each next item and replace the best when you find a better one. Starting at 0 is a bug when all values are negative; start with the first item (or -Infinity / Infinity).

javascript
const temps = [31, 35, 29, 38, 33];
let hottest = temps[0];
for (const t of temps) {
  if (t > hottest) hottest = t;
}
console.log(hottest); // 38

4. The builder

Make a new array or string from an old one: start with [] or '' and add to it inside the loop. Later you will write the same thing with map and filter (module 4).

javascript
const names = ['asha', 'ravi', 'meena'];
const upper = [];
for (const n of names) upper.push(n.toUpperCase());
console.log(upper); // ['ASHA', 'RAVI', 'MEENA']

5. Nested loops

A loop inside a loop handles two dimensions: rows and seats, days and hours. The inner loop runs completely for every round of the outer loop, so 10 rows × 20 seats = 200 inner rounds.

javascript
for (let row = 1; row <= 3; row++) {
  let line = '';
  for (let col = 1; col <= row; col++) line += '*';
  console.log(line);
}
Prints *, then **, then *** on three lines.

Off-by-one errors

Careful: The most common loop bug is running one time too many or too few: i <= arr.length reads past the end (arr[arr.length] is undefined), and i < n - 1 misses the last item. For an array, the safe pattern is for (let i = 0; i < arr.length; i++). Check the first and last rounds by hand.
Think of it like this: These patterns are like basic cooking techniques: boiling, frying, steaming. Once you know them, any new recipe is just a combination. A "find the highest-paid employee in each department" problem is a nested loop with a best-so-far inside.
Tip: Before writing a loop, write one sentence: "I will go through ___ and keep track of ___." That sentence tells you which pattern to use and what variable to create before the loop.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Loop patterns that solve real problems · 1/7

Loop patterns

In this lesson you will learn five loop patterns that solve most everyday problems.

Prefer a video by a teacher? Find free videos on “javascript loop practice problems accumulator fizzbuzz” on YouTube ↗

In real life: Finding the top seller in a kirana shop

A shopkeeper exports a day's sales as pairs of item and quantity. To restock, he wants the total units sold and the single best-selling item. That is an accumulator plus a best-so-far in one loop.

javascript
const sales = [['Milk', 42], ['Bread', 18], ['Eggs', 55], ['Tea', 30]];
let units = 0;
let best = sales[0];
for (const sale of sales) {
  units += sale[1];
  if (sale[1] > best[1]) best = sale;
}
console.log(units, best[0]); // 145 Eggs

Practice (0/3 done)

Task 1 · Code · Javascript

Write a function maxValue(nums) that returns the largest number in a non-empty array. It must work when all numbers are negative.

Task 2 · Code · Javascript

Write fizzBuzz(n) that returns an array of the numbers 1 to n as strings, but "Fizz" for multiples of 3, "Buzz" for multiples of 5 and "FizzBuzz" for multiples of both.

Task 3 · Code · Javascript

Write charCount(text) that returns an object counting each character, ignoring spaces. Example: charCount("aab") returns { a: 2, b: 1 }.

Quick quiz

Question 1

1.For "find the minimum", what is the safest starting value?

Question 2

2.Outer loop runs 4 times, inner loop runs 5 times each. How many inner rounds in total?

Question 3

3.for (let i = 0; i <= arr.length; i++) on [1, 2, 3]: what is arr[i] in the last round?

Question 4

4.Why use break in a search loop?

Read more (free)

Before this, learn

This topic builds on these. If something here feels new, open them first.

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

For "find the minimum", what is the safest starting value?

Answer: The first item of the array

Starting with 0 gives a wrong answer when all values are positive (for min) or negative (for max).

Outer loop runs 4 times, inner loop runs 5 times each. How many inner rounds in total?

Answer: 20

The inner loop runs fully for each outer round: 4 × 5 = 20.

for (let i = 0; i <= arr.length; i++) on [1, 2, 3]: what is arr[i] in the last round?

Answer: undefined

i reaches 3, and arr[3] does not exist, so it is undefined: an off-by-one bug.

Why use break in a search loop?

Answer: To stop as soon as the item is found

Once found, looking further wastes time.

You want to multiply many numbers together in a loop. What should the accumulator start at?Related

Answer: 1

Multiplying by 1 changes nothing, so 1 is the right start. Starting at 0 would make the result 0.

From Common loop patterns

A list has 5 items. Which index is the last one?Related

Answer: 4

The last index is always len - 1, so 5 - 1 = 4. You can also use -1.

From Lists: many values in one name

A table has 10 rows; the email column is NULL in 3 of them. What is COUNT(email)?Related

Answer: 7

COUNT(column) counts only rows where the column has a value: 10 - 3 = 7.

From Counting and totals: aggregate functions

customers has 6 rows and 2 have no email. What does COUNT(email) return?Related

Answer: 4

COUNT(column) counts only values that are not NULL.

From Aggregate functions

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. This is the last topic of “Strings, decisions and loops”. The module exam comes next.
  2. Module 2 exam: Strings, decisions and loops · 12 questions · 25 min, without help. 5 topics of this module still to finish first.
  3. Then the next module, Functions and closures. 61 topics left in the course before the final exam.

← Previous: Loops: for, while, do…while, for…of and for…in