Why you should use Array.some instead of 'for' loop or forEach?
Tags: javascript, webdev, angular, react
Published: 2021-07-15 14:02:46

In this article, we are going to learn why we should use [Array.some](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some) instead of  [Array.forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/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.

```javascript
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

```javascript
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**:

```javascript
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: 


```javascript
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**:

```javascript
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

```javascript
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](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some) ,
> 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,

```javascript
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.

```javascript
const isFailed = marks.some((subject) => {
  console.log("checking subject => " + subject.name);
  return subject.mark < 40;
});
console.log("Is student failed => " + isFailed);
```

**Output:**

```javascript
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](https://twitter.com/yuvgeek) & [Github](https://github.com/yuvgeek) 🙂

###  Support 🙌 

<a href="https://www.buymeacoffee.com/yuvgeek">Buy me a coffee</a>