Count Certain Elements of an Array in JavaScript
Tags: programming, tutorial, javascript
Published: 2022-03-17 07:45:29

![An yellow background with the following text: "Array in JavaScript" inside a square brackets symbol](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rdy504lxg25f2zs5ugun.png)

Introducing the `.filter` method that can be used literally to filter array elements based on a condition, we can use it in addition to the `.length ` property to count certain elements of an array. The condition of the `.filter` method is provided by a function, passed as parameter.  Also, we will introduce the `.reduce` method that executes a function for each element in the array and return a single value.

The function passed as parameter can be either an arrow function or a common function as a callback function, and it will dictate what elements the `.filter` will add or not to the returned array or what exactly the `.reduce` method will do for each elements in the array.

## Count Certain Elements of an Array in JavaScript using the `.filter` Method

The `.filter` is a method of the `Array` entity that returns a new array filtered by the provided condition. Returning a new array, means that the original array which the method is called will stand immutable. For example, if we want all elements that is equal to the value 'one' in an array, we can use the `.filter` as below:

```javascript
// Input
let array = ['one', 'two', 'three', 'four', 'five']
array = array.filter(element => element == 'one')
console.log(array)
```

Output:

```javascript
// Output
[ 'one' ]
```

As expected, the `.filter` method returned an array based on the `element == 'one'` condition. So if the actual element of the array is equal to `'one'`, then the filter will add this element to the returned array.

But what is happening inside the `.filter` method? We can see better by using a common function structure to the `condition()` function:

```javascript
// Input
let array = ['one', 'two', 'three', 'four', 'five']
array = array.filter(function condition(element) {
    if (element == 'one') return true
    return false
})
console.log(array)
```

With this, we have the same first example output:

```javascript
// Output
[ 'one' ]
```

The `condition()` function receives an `element` as parameter, and if this `element` is equals to a certain value, in this case `'one'`, it returns `true` and if not, returns `false`. So, the `.filter` method add any of the `element` that the condition results in `true`; as the original array has only the first element as `one`, the `.filter` return only one element.

Note that the `condition()` function is declared inside the `.filter` method. If you declare it outside and call it inside the `.filter`, it will not work, because the `element` is part of the callback scope.

Basically, a callback function is a function passed as parameter to another function which is called "outer function". The callback function will be called by the outer function to do something; in the case of the `.filter` method, it will call the `condition()` callback function to filter the array based on its condition.

Back to our objective, the `.filter` will finally return a new array that have `array.length` elements, which each one is an element that the callback function returned a value equivalent to `true`. As we want to count these filtered elements, we can easily do this with the `.length` property.

The `.length` is as property of the Array entity that returns the number of elements in an array. This number is always greater than the highest index in that array, because the first element is always on the index equals to `0`.

```javascript
// Input
let array = [1, 2, 3, 4, 5]
console.log(array.length)
```

Output:

```javascript
// Output
5
```

The number of elements in the `array` is 5. 5 is a number greater than the index of the value `5`, that is 4.

Putting all together, as an example we can use the following: How to get the number of all test notes of an school, that are greater than seven? The array of the test notes is in the example.

```javascript
// Input
let notes = [7.0, 6.7, 7.3, 9.8, 5.6, 7.1, 7.8, 6.2, 8.0, 9.0, 4.5, 6.9, 7.5, 8.5, 6.4]
greaterThanSeven = notes.filter(value => value > 7)
console.log(greaterThanSeven.length)
```

Output:

```javascript
// Output (The array returned by the .filter is: [7.3, 9.8, 7.1, 7.8, 8, 9, 7.5, 8.5])
8
```

So, `8` is the number of notes that are greater than 7 of all 15 notes in the original `notes` array. 

Now, as another option we can use the `.reduce` Array entity method. This method is used to execute a callback function (as well as the `.filter`) on each element of the array, but it will finally return a single value.

A simple example to the `.reduce` working, is the sum of all element in an array:

```javascript
// Input
let array = [1, 2, 3, 4, 5].reduce((previous, current) => previous + current)
console.log(array)
```

Output:

```javascript
// Output
15
```

But this method can be used in other way, that is by passing the initial value. In the previous example, we can see that the `previous` begin with the first index element in the array, being the callback function, this way:

```javascript
/*
previous + current = result
1 + 2 = 3
3 + 3 = 6
6 + 4 = 10
10 + 5 = 15 -> final result
*/
```

This sum is working correctly because if we don't pass a second parameter (as the callback function is the first parameter) to the `.reduce` method, it will consider `previous` as the first element of the array in the first iteration.

But if we want to count certain elements in the array? We cannot use the first element as the `previous`, because it could result in a wrong value. The example below is about counting how many 2 numbers are in the array:

```javascript
// Input
let array = [1, 2, 3, 4, 5].reduce((sum, value) => (value == 2 ? sum + 1 : sum))
console.log(array)
```

Output:

```javascript
// Output
2
```

As we can see, the result is `2`, but the correct answer is `1`. This happened because the `sum` is being initialized with the first element `1`, as we don't passed any other parameter beyond the callback function. To do the correction, we can just pass a `0` as the second `.reduce` parameter:

```javascript
// Input
let array = [1, 2, 3, 4, 5].reduce((sum, value) => (value == 2 ? sum + 1 : sum), 0)
console.log(array)
```

Output:

```javascript
// Output
1
```

This way, the `.reduce` is making `sum + 1` every time that the current element is equal to 2, with the `sum` being initialized with `0`.

## Extra

As a plus, instead of using all theses logics every time that we need to count certain elements in an array, we can use the `.prototype` Array entity property to write custom methods or properties to this entity.

To make a `.countCertainElements` method to the Array entity, we can use the following structure:

```javascript
// Input
// Declaring the prototype .countCertainElements method
Array.prototype.countCertainElements = function(value){
    return this.filter(arrayElement => arrayElement == value).length
}
let array1 = [1, 2, 2, 2, 3, 4, 5]
console.log(array1.countCertainElements(2))
```

Output:

```javascript
// Output
3
```

And the same can be done for the `.reduce`:

```javascript
// Input
// Declaring the prototype .countCertainElements method
Array.prototype.countCertainElements = function(value){
    return this.reduce((sum, element) => (element == value ? sum + 1 : sum), 0)
}
let array1 = [1, 2, 2, 2, 3, 4, 5]
console.log(array1.countCertainElements(2))
```

Output:

```javascript
// Output
3
```