What the code is supposed to do
The function checkForPositive receives an array of numbers and should return true if at least one of them is greater than zero, and false otherwise. The code below the function calls it with [-1, 2, 3] and prints a sentence based on the result. Since 2 and 3 are positive, the program should print Array has positive numbers.
The code you start with prints the other sentence, Array doesn't have positive numbers:
function checkForPositive(nums: number[]): boolean {
for (const num of nums) {
if (num > 0) {
return true;
} else {
return false;
}
}
}
// Do not change this code:
if (checkForPositive([-1, 2, 3])) {
console.log("Array has positive numbers");
} else {
console.log("Array doesn't have positive numbers");
}
Your job is to find the mistake in checkForPositive and fix it.
What goes wrong
Follow the loop for [-1, 2, 3]. On the first pass, num is -1. The condition num > 0 is false, so the else branch runs, and it contains return false. A return ends the function on the spot. The loop never gets to 2 or 3, and the answer is false.
The reasoning behind the bug is understandable: "this number is not positive, so the array has no positive number". But one number that is not positive tells you nothing about the others. The array has a positive number if any element is positive, so you can only say there is none after looking at every element.
The function as written checks just the first element and answers for the whole array based on it. For an array that starts with a positive number it happens to work, which can make the bug hard to spot with a single test.
A second consequence hides in the same code. For an empty array the loop body never runs, and the function ends without any return. A function that reaches its end without returning a value produces undefined, and the if in the calling code treats undefined as false. The output is the same sentence as for "no positive numbers", but only by accident.
The shape of the fix
Two different situations call for two different returns:
- Finding a positive number settles the question immediately: the answer is
true, and returning from inside the loop is right. - Not finding one can only be known once the loop has ended. So the
falsebelongs after the loop, not inside it.
This is the same pattern as any "does it exist?" search. A match returns early. The default answer waits at the end.
Fixing it step by step
- Delete the
elsebranch. Without it, a non-positive number simply lets the loop move on to the next element. - Keep the
return true. It stays inside theifso it runs as soon as a positive number turns up. - Add
return falseafter the loop. It runs only when every element has been checked and none was positive. It also covers the empty array. - Leave the calling code alone. The task says not to change it.
The fixed code in TypeScript
function checkForPositive(nums: number[]): boolean {
for (const num of nums) {
if (num > 0) {
return true;
}
}
return false;
}
if (checkForPositive([-1, 2, 3])) {
console.log("Array has positive numbers");
} else {
console.log("Array doesn't have positive numbers");
}
With the fix, the program prints:
Array has positive numbers
Some TypeScript details in this code:
- The return type is a promise to the compiler only. The annotation
: booleansays what the function should give back, and tsc checks thereturnstatements against it. It does not change what happens when the program runs. In the lessons the buggy version compiles without complaint and returnsundefinedfor an empty array. - A function can reach its end without returning. In JavaScript this produces
undefined. The finalreturn falseremoves that possibility, so the function always returns a realtrueorfalse. - Zero is not positive. The condition is
num > 0, with a strict comparison, so[0]givesfalse. - The
ifaccepts the returned boolean directly. The calling code writesif (checkForPositive(...))without comparing the result totrue.
Common mistakes
- Moving
return falsebut keeping it in the loop. If it stays in the loop in any form, one element decides for the whole array. - Swapping to
num < 0. The question is about positive numbers, so the condition must remainnum > 0. - Using
>=. Withnum >= 0, a zero would count as positive. - Counting instead of returning. Counting all the positive numbers and checking whether the count is above zero works, but it always visits the whole array, while the early return stops at the first match.
- Editing the lines at the bottom. Changing the printed sentences or the argument may make the output look right while the function is still wrong.
Testing
[-1, 2, 3]returnstrue, so the program printsArray has positive numbers.[-1, -2]returnsfalse.[2, -1]returnstrue. The buggy version also gets this one right, which shows why it needs a test that starts with a non-positive number.[]returnsfalse.[0]returnsfalse.