Define the report
We need the sum, average, minimum and maximum of order totals [20, 35, 15]. Predict them: 70, 70/3, 15 and 35. Should an empty report claim the average is zero? Decide explicitly.
const totals = [20, 35, 15];
let sum = 0;
let minimum = null;
let maximum = null;
for (const total of totals) {
sum += total;
if (minimum === null || total < minimum) minimum = total;
if (maximum === null || total > maximum) maximum = total;
}
const average = totals.length === 0 ? null : sum / totals.length;
console.assert(sum === 70);
console.assert(minimum === 15);
console.assert(maximum === 35);
console.assert(average === 70 / 3);
for...of supplies each value. Use an index-based for loop when the position is needed. The conditional expression condition ? first : second chooses one value; use if/else if a longer decision reads better. Here null means no result for an empty collection.
Starting minimum at zero would be wrong for these positive totals. Starting maximum at zero would be wrong if all values could be negative. Initialize from actual data or use an explicit no-result state.
forEach and its limits
totals.forEach((total) => console.log(total)) calls a callback for each entry. It is useful for side effects but does not build a result collection. Return inside its callback does not break the surrounding iteration. Use for...of when break or continue is part of the logic.
Independent exercise
Find the first total above 30 in [20, 35, 15], then count all totals above 30. Explain why the first operation may stop early while the second cannot.
Correction
The first match is 35; the count is 1. A search can break after finding 35 because later values cannot change the first match. Counting must examine the rest. With an empty array, return null for this search convention and zero for the count.
Review
Assume valid numeric entries here. Invalid entries require an explicit reject-or-skip policy, not accidental comparisons. Always state what an empty collection means for each statistic.