A while ago, I came across a question from a student who wanted to iterate over numbers in a list and return true if there is a duplicated number.
The code was as follows and the student wondered why it didn't behave as she expected.
function containsDuplicate(nums) {
const dups = [];
nums.forEach((num) => {
if (dups.includes(num)) {
return true; // Found a duplicate
}
dups.push(num);
});
return false; // No duplicates found
}
const nums = [1, 2, 3, 3, 5];
console.log(containsDuplicate(nums));
In the above code, ForEach
iterates over the numbers and adds the non-duplicated numbers to another list named dups
. It will return true
as soon as a duplicate is found otherwise it returns false
.
It seems pretty straightforward. Doesn't it?
But despite existing duplicates in the array, calling containsDuplicate(nums)
returns false
.
So why does it happen?
The problem hides behind using return true
inside the ForEach loop and expecting it to exit early and return the true
value as the result of invoking containsDuplicate(nums)
. That is a false expectation.
In a forEach
loop (or other higher-order functions like map
, filter
, etc.), a return statement inside the callback function will only exit the current iteration of the loop, not the entire loop nor the function itself. The loop will continue to the next iteration.
So how could we solve the problem?
One approach could be using the for..of
loop instead of ForEach
.
So let's modify the above code as follows.
function containsDuplicate(nums) {
const dups = [];
for (const num of nums) {
if (dups.includes(num)) {
return true; // Found a duplicate
}
dups.push(num);
}
return false; // No duplicates found
}
const nums = [1, 2, 3, 3, 5];
console.log(containsDuplicate(nums));
Now it behaves as expected. That is because, in the for...of
loop (which is not a higher-order function), the return statement will exit the loop and the function (or block scope) in which it is used.
Conclusion: Beware of the temptation to use the return
statement for early-exiting in the context of higher-order functions.
If you found this post helpful, please like and share. Your comments and discussions are warmly welcomed.
Always love learning from my peers and receiving the gift of feedback.
Happy coding!
Top comments (0)