JavaScript Higher Order Functions
Tags: javascript
Published: 2020-11-16 13:34:12

Coding in Javascript gets easier and easier every day once you learn more about the language. I personally have experienced this in my coding journey. I started with the normal for and while loops. That is until I came across the Javascript higher-order functions. Higher-order functions are functions that take other functions as arguments or return functions as their results. JavaScript's higher-order functions are actually quite easy to understand. They also provide a clean simple syntax to write your code, this will help you achieve more with much less code needed.

In this article, I will take you through some of the commonly used higher-order functions. I will try to show an implementation using for, while loops, and if statements and simplify the same with the higher-order functions. 

```js
const  footballers=[
{name:'Brian',position:'midfield',number:22},{name:'james',position:'midfield',number:44},{name:'Bruno',position:'keeper',number:1},{name:'Ramos',position:'defender',number:2},{name:'martinez',position:'forward',number:7},{name:'ozil',position:'midfield',number:10},{name:'emery',position:'striker',number:9},{name:'John',position:'defender',number:5},{name:'evra',position:'defender',number:3},{name:'sane',position:'forward',number:13},{name:'sandro',position:'midfield',number:14},{name:'Emerik',position:'keeper',number:100},{name:'brent',position:'midfield',number:22}
]
```

I have added some data above to play with. In the first example, let's try to output a list of all names and save them in a new array called names.
## 1. forEach

```js
let names=[]

for (let i=0;i<footballers.length;i++){
names.push(footballers[i].name)
}
console.log(names)
//name array includes
//[
//     'Brian',    'james',
//     'Bruno',    'Ramos',
//     'martinez', 'ozil',
//     'emery',    'John',
//     'evra',     'sane',
//     'sandro',   'Emerik',
//     'brent'
//   ]


```
Above results, the same can be done using a forEach loop in one line as below as shown below.

```js
let names=[]

 footballers.forEach(footballer => names.push(footballer.name))
//names array returned will have
//[
//     'Brian',    'james',
//     'Bruno',    'Ramos',
//     'martinez', 'ozil',
//     'emery',    'John',
//     'evra',     'sane',
//     'sandro',   'Emerik',
//     'brent'
//   ]

```
## 2. filter
Assume we have an array of ages and we want to filter and remain with ages from 13-20 included only:-
```js
const ages =[20,15,14,12,8,9,3,21,40,51,35,17,19,17,12,18]
const teen =[]
for(let i=0;i<ages.length;i++){
    if(ages[i]> 13 && ages[i] <= 20){
        teen.push(ages[i])
    }

}
console.log(teen)
//teen array after loop
// [
//     20, 15, 14, 17,
//     19, 17, 18
//   ]

```
when using the filter function however the code is as follows:-
```js
let teen = ages.filter(age =>{
    if(age >=13 && age<= 20 ){
        return true
    }
})
console.log(teen)
//teen constant
// [
//     20, 15, 14, 17,
//     19, 17, 18
//   ]

//another example("return forwards only")
let forwards =footballers.filter(footballer => footballer.position === 'forward')
// forwards
// [
//     { name: 'martinez', position: 'forward', number: 7 },
//     { name: 'sane', position: 'forward', number: 13 }
//   ]


//another example("return nonMidfielders only")

let nonMidfielder =footballers.filter(footballer => footballer.position !== 'midfield')

// [
//     { name: 'Bruno', position: 'keeper', number: 1 },
//     { name: 'Ramos', position: 'defender', number: 2 },
//     { name: 'martinez', position: 'forward', number: 7 },
//     { name: 'emery', position: 'forward', number: 9 },
//     { name: 'John', position: 'defender', number: 5 },
//     { name: 'evra', position: 'defender', number: 3 },
//     { name: 'sane', position: 'forward', number: 13 },
//     { name: 'Emerik', position: 'keeper', number: 100 }
//   ]

```
In the 2nd implementation with the filter function, there is no need for creating a new array and pushing onto it.
## 3. Map
Map function gives us a one-to-one relationship, we can use this relationship to mutate or manipulate the data in whichever method we want:-

```js
//using a for loop
let positions =[]
for(let i = 0;i<footballers.length;i++){
    positions.push(footballers[i].position)


}


// positions array 
//[
//     'midfield', 'midfield',
//     'keeper',   'defender',
//     'forward',  'midfield',
//     'forward',  'defender',
//     'defender', 'forward',
//     'midfield', 'keeper',
//     'midfield'
//   ]

//using a map function
let positions = footballers.map(footballer => footballer.position)

// positions array 
//[
//     'midfield', 'midfield',
//     'keeper',   'defender',
//     'forward',  'midfield',
//     'forward',  'defender',
//     'defender', 'forward',
//     'midfield', 'keeper',
//     'midfield'
//   ]


console.log(positions)
``` 
Again when using a for a loop a positions array first needs to be created then inside the loop push into the array after every iteration. However, when using a Map function the results of the map function are set to the constant positions. Using map function enables you to get the same results with fewer lines of code and fewer steps i.e no creating a new array and pushing onto it. You can also pass an optional index argument as the 2nd argument to the map function.

```js
let positions = footballers.map((footballer,index) => `${index}: ${footballer.position}`)

 // the following is logged on the console with the index on the left
//  [0: midfield
// 1: midfield
// 2: keeper
// 3: defender
// 4: forward
// 5: midfield
// 6: forward
// 7: defender
// 8: defender
// 9: forward
// 10: midfield
// 11: keeper
// 12: midfield]
```
## 4. sort
The sort function simply sorts the data from lowest to largest or largest to smallest. It takes two positional arguments that are moved up and down making comparisons in order to sort an array.

```js

const sortedFootballers =footballers.sort((a,b) =>(a.number >b.number? 1 :-1))


// sorted by number from smallest to highest
//[
//     { name: 'Bruno', position: 'keeper', number: 1 },
//     { name: 'Ramos', position: 'defender', number: 2 },
//     { name: 'evra', position: 'defender', number: 3 },
//     { name: 'John', position: 'defender', number: 5 },
//     { name: 'martinez', position: 'forward', number: 7 },
//     { name: 'emery', position: 'forward', number: 9 },
//     { name: 'ozil', position: 'midfield', number: 10 },
//     { name: 'sane', position: 'forward', number: 13 },
//     { name: 'sandro', position: 'midfield', number: 14 },
//     { name: 'brent', position: 'midfield', number: 22 },
//     { name: 'Brian', position: 'midfield', number: 22 },
//     { name: 'james', position: 'midfield', number: 44 },
//     { name: 'Emerik', position: 'keeper', number: 100 }
//   ]


//other examples


let sortedAges =ages.sort((a,b)=> a-b)

//arranged from smallest to highest
// [
//     3,  8,  9, 12, 12, 14,
//    15, 17, 17, 18, 19, 20,
//    21, 35, 40, 51
//  ]

 sortedAges =ages.sort((a,b)=> b-a)

//arranged from highest to smallest
//  [
//     51, 40, 35, 21, 20, 19,
//     18, 17, 17, 15, 14, 12,
//     12,  9,  8,  3
//   ]


console.log(sortedAges)


```

## 5. reduce
The reduce function takes two positional arguments the 1st is an accumulator the other the iterated value and it returns the accumulated value.

```js
// the total of all the ages array
//using a for loop 
let total = 0
for(let i=0;i<ages.length;i++){
    total+=ages[i]
}
console.log(total)
//total
// 311

//using reduce 
// last argument is zero ("the starting value of total")

let agesTotal = ages.reduce((total,age)=> total+age,0)

console.log(agesTotal)
// 311

let names = footballers.reduce((start,footballer) => start + " " + footballer.name ,"")

console.log(names)
// names combined , this is to show reduce can also be used on strings
// Bruno Ramos evra John martinez emery ozil sane sandro brent Brian james Emerik

```
conclusion
I hope I helped you gain insight into JavaScript Higher Order functions and their usage.