Useful Higher-Order Functions in Javascript
Tags: javascript, higherorderfunctions, fuctionalprogramming
Published: 2020-12-04 05:10:32

What makes Javascript suitable for functional programming is that it accepts Higher-Order Functions. Higher-Order Functions are extensively used in Javascript.

# What is Higher-Order Function?
A higher-order function is a function that receives a function as an argument or returns the function as an output.
Taking other functions as arguments is often referred to as a callback function because it is called back by the higher-order function. This is a concept that Javascript uses a lot.

For example, `.map()`, `.filter()` , `.reduce()` etc. are the some built-in higher order functions.

So let’s discuss some of the useful built-in higher-order functions in Javascript.

# .map()
Let’s look at this array method with a simple example. Say you have received an array containing multiple objects — each one representing a person. The thing you need in the end is an array containing only the names of reach person.
```
// You have:
const persons = [
{id: 1, name: 'John'},
{id: 2, name: 'Bob'},
{id: 3, name: 'Adam'}
];
// What you need:
['John', 'Bob', 'Adam'];
```
There are multiple ways to achieve this. You might want to do it by creating an empty array then using `.forEach()` , `for(…of)`, or simply `for()` to meet your goal.

But now let’s see with a `.map()` method.
```
const personsName = persons.map(person => person.name);
```

## How does .map() works?
It takes two arguments, a callback and an optional context (will be considered as ‘`this`’ in the callback). The callback runs for each value in the array and returns each new value in the resulting array.

Note: the resulting array will always be the same length as the original array.


# .reduce()
Just like `.map()`, reduce also runs a callback for each element of an array. What’s different here is that reduce passes the result of this callback (the accumulator ) from one array element to the other.
The accumulator can be anything such as integer, string, object, array, etc… and must be instantiated or passes when calling `.reduce()`.
Let’s look at an example.
```
const players= [
    {id: 10, name: 'John', points: 57},
    {id: 11, name: 'Kyle', points: 52},
    {id: 12, name: 'Bob', points: 63}
];
```
We need to know the total points of all of them. With `.reduce()`, it’s pretty straight-forward.

```
const totalPoints = players.reduce((accumulator, person) => {
    return accumulator + person.points;
}, 0);   //172
```
After running the callback for each element of the array, reduce will return the final value of our accumulator (in our case ‘0’).

Now let’s say I want to find which player has the highest points. For that, I can also use it as well.

```
const highestPlayer = players.reduce((lowest, player) => {
    return (lowest.points || 0) > player.points ? lowest : player
}, {});
```

I named my accumulator ‘lowest’. My callback compares the accumulator to each player. If a player has more points than the lowest, then the player becomes the new lowest. So that the one I return.
So, using `.reduce()` is an easy way to generate a single value of an object from an array.

# .filter()
What if you have an array, but only want some of the elements in it? That's where `.filter()` comes in!

Here’s our data:
```
const persons = [
   {id: 1, name: 'John', profession: 'Engineer'},
   {id: 2, name: 'Bob', profession: 'Developer'},
   {id: 3, name: 'Rocky', profession: 'Singer'},
   {id: 4, name: 'Kyle', profession: 'Developer'}
];
```
Say, we want an array of people having the profession of ‘Developer’ only. With `.filter()`, it could be a lot easier.

```
const developer = persons.filter(person => {
   return person.profession === 'Developer';
});
```
Basically, if the callback function returns true, the current element will be in the resulting array. If it returns false, it won't be.

# .some()
This array method helps you determine if one or more of its values correspond to something you’re looking for.

Let’s illustrate with an example. Here is a list of random numbers in an array.

```
const numbers = [1, 2, 3, 4, -1, -2, 5];
```

You want to know if there are any negative numbers. There are many ways to achieve that goal. But `.some()` might be an easy way.

```
const hasNegativeNumbers = numbers.some(number => number < 0); //true
```

## How does it work?
Well, you pass `.some()` a function as an argument. That function runs for each value in the array. You can then see if the value fits the condition you’ve written. The function must return a boolean (although a truthy/falsy) value works as well. As soon as one true is returned, `.some()` will itself return true. If none of the values when processed in your condition returns true(if they all return false) then .some() will return `false`.

Note: As soon as a single true is returned, `.some()` will stop checking the other array values.

# .every()
This array method works similarly to the `.some()` but it checks if every element or value passes a particular test.

Let's illustrate with an example.
```
const numbers = [1, 2, 3, 5, 6, 11, 23, 45];
```

You want to know that all the numbers are greater than 0, then with `.every()` it’s pretty straight-forward.

```
const allPositiveNumbers = numbers.every(number => number > 0); //true
```

It will check each and every element in an array and returns true if all values meet the criteria, false if not.

# .find()
This array method does exactly what it says. It finds what you’re looking for. The .find() will return the first value that corresponds to the passed condition. Let’s see with an example.

Here is our list of persons.

```
const persons = [
   {id: 1, name: 'Ricky', developer: false},
   {id: 2, name: 'Jack', developer: true},
   {id: 25, name: 'Chris', developer: false}
];
```

If we want an object who has a ‘developer ’ property to true, we can output the value by using `.find()`.

```
const developer = persons.find(person => person.developer);
```
Note: if it doesn’t find then it will return `undefined`.

## What is the difference between `.filter()` and `.find()` ?

`.find()` will return the first match. If more values match your condition then it won’t matter. Only the first match will be returned. If you need a list of all matched then you can use `.filter()` instead of `.find()`.

# Conclusion:

These are the few commonly used built-in higher-order functions. A higher-Order function is a function that may receive a function as an argument and can even return a function.

Higher-Order functions are just like regular functions with an added ability of receiving and returning other functions as arguments and outputs.