Why you should use Array.some instead of 'for' loop or forEach?

Why you should use Array.some instead of 'for' loop or forEach?

ยท

4 min read

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 ๐Ÿ™‚

Support ๐Ÿ™Œ

Did you find this article valuable?

Support Yuvaraj by becoming a sponsor. Any amount is appreciated!

ย