In this article, we are going to learn why we should use Array.some instead of Array.forEach (or) for loop.
Objective
In a given array, find if the student failed in any one of the subjects. The pass criteria for students is to score at least 40 marks in all the subjects.
const marks = [
{ name: "English", mark: 80 },
{ name: "Maths", mark: 100 },
{ name: "Science", mark: 38 },
{ name: "Social", mark: 89 }
];
Traditional approach
Solution 1: Using Array.forEach
let isFailed = false;
marks.forEach((subject) => {
console.log("checking subject => " + subject.name);
if (subject.mark < 40) {
// failed
isFailed = true;
}
});
console.log("Is student failed => " + isFailed);
Output:
checking subject => English
checking subject => Maths
checking subject => Science
checking subject => Social
Is student failed => true
The student is failed because he doesn't meet the pass criteria in the Science subject.
But, if you look at the output, it is unnecessary to check the Social subject because he failed in Science subject and the position of Science subject is before Social. So, in order to stop further checking, we can update the existing code as below:
let isFailed = false;
marks.forEach((subject) => {
// added this condition to prevent further checking
if (!isFailed) {
console.log("checking subject => " + subject.name);
if (subject.mark < 40) {
// failed
isFailed = true;
}
}
});
console.log("Is student failed => " + isFailed);
Output:
checking subject => English
checking subject => Maths
checking subject => Science
Is student failed => true
This looks like we have solved the issue but it's not. Even though we wrapped our logic inside if block, the iteration still happens. Try checking it by adding else block.
Imagine if we have 1000 elements in an Array and if the condition to fail is at 10th position, then the remaining 990 iteration still runs which is not needed. It takes both time & computation. ๐คฏ
So, this is the Wrong solution to this problem. โ
Let's move on to the second traditional approach.
Solution 2: Using for() loop
let isFailed = false;
for (i = 0; i <= marks.length; i++) {
const subject = marks[i];
console.log("checking subject => " + subject.name);
if (subject.mark < 40) {
// failed
isFailed = true;
// prevents further execution
break;
}
}
console.log("Is student failed => " + isFailed);
This solution is better than the previous approach. The reason is, when the fail condition is met, further iteration is stopped with break
keyword.
The break statement is used to jump out of a loop
The problem with this approach is, this is not the right way to solve this problem. Like how we use the for loop & Array.forEach to iterate the Array, there is an inbuilt Array method to solve this problem.
So, this is also not a correct solution. โ
Let's see in the next section!
Correct Approach
The correct approach to solve this problem is to use, Array.prototype.some()
.
From MDN ,
The some() method tests whether at least one element in the array passes the test implemented by the provided function. It returns true if, in the array, it finds an element for which the provided function returns true; otherwise it returns false. It doesn't modify the array.
This is what we wanted. If at least one element passes the condition, it should return true otherwise it should return as false.
Here is the solution to our problem,
const isFailed = marks.some((subject) => subject.mark < 40);
console.log("Is student failed => " + isFailed); // true
This works as expected. The solution is in a single line. ๐คฏ
But, how do we know, if further execution is stopped once the condition is met?
Let's check it out by updating the code.
const isFailed = marks.some((subject) => {
console.log("checking subject => " + subject.name);
return subject.mark < 40;
});
console.log("Is student failed => " + isFailed);
Output:
checking subject => English
checking subject => Maths
checking subject => Science
Is student failed => true
The code works as expected.
So, this is the correct solution to solve our problem. โ
Now, the Code is much readable, simpler & efficient than the other approaches.
I hope you enjoyed this article or found it helpful.
You can connect with me on Twitter & Github ๐