How to select the right HOF's to use
Tags: javascript, beginners, programming, webdev
Published: 2022-08-30 20:13:32

**_Hey Devs!_** 🌼

I am a full-stack dev student, and today I'll be helping you to select the correct **High Order Function (HOF)** to use in your situation.

We use HOF's with _arrays_. HOF's run through each element of an array, just like when we use a simple `for` function, but easier. 

I will use the result of the endpoint "_/characters_" from the Breaking Bad API to apply these functions. [available [here](https://breakingbadapi.com/)]

The HOF's I'll be speaking about in this article are: **forEach, map, find, some, every, filter, sort,** and **reduce**.

## Params in HOF's

These functions already have original parameters.
- **First param:** the current element.
-  **Second param:** the index of the current element.
-  **Third param:** the entire array.

```javascript
const array = [0, 1, 2, 3, 4];
array.forEach((element, index, allArray) => {
  console.log(`The element ${element} is in the position ${index} of the array ${allArray}`);
});

/* this code output:
The element 0 is in the position 0 of the array 0,1,2,3,4
The element 1 is in the position 1 of the array 0,1,2,3,4
The element 2 is in the position 2 of the array 0,1,2,3,4
The element 3 is in the position 3 of the array 0,1,2,3,4
The element 4 is in the position 4 of the array 0,1,2,3,4
*/
```

## Funtions

### `.forEach()`
The most important feature of this function is that **it doesn't return anything**. Because of this, we use it when we want that the function realizes something without needing anything in return. Which means we don't need to assign it to a const.

```js
const  characters  =  require('../characters-data/characters');

const  result  =  characters.forEach((cur) =>  console.log(cur.name));
/*
Walter White
Jesse Pinkman
...
Ignacio Varga
Eduardo Salamanca
*/

console.log('Result of const: ', result);
// Result of const: undefined
```

### `.map()`
Very similar with the `.forEach()` function. The difference is that this function **returns an array with the same length as the original** one. In my projects, I mostly use it to render all the elements present in an array inside a React Component.

```js
const  characters  =  require('../characters-data/characters');

const  result  =  characters.map((cur) =>  cur.name);

console.log(result);
/*
[ 'Walter White', 'Jesse Pinkman', 'Skyler White', ...  'Ignacio Varga', 'Eduardo Salamanca' ]
*/
```

### `.filter()`
As the own name suggests, this function filters our array according to a verification made by us. We only need to create the conditional test, and the filter will check if the result returns true or false. If true, the current element will be part of the **array returned**.

This function is my favorite. We can use it to create an array with the values we want. Really useful.

```js
const  characters  =  require('../characters-data/characters');

const  result  =  characters.filter((cur) =>  cur.name.includes('White'));

console.log(result);
/*
[
	{
		char_id: 1,
		name: 'Walter White',
		...
	},
	{
		char_id: 3,
		name: 'Skyler White',
		...
	},
	{
		char_id: 4,
		name: 'Walter White Jr.',
		...
	},
	{
		char_id: 39,
		name: 'Holly White',
		...
	}
]
*/
```

When none of the elements fit the condition, the function returns an **empty array**.

```js
const  characters  =  require('../characters-data/characters');

const  result  =  characters.filter((cur) =>  cur.name.includes('Bla Bla Bla'));

console.log(result); // []
```

### `.find()`
This function is like the filter. We need to pass a conditional, but only the **first element** to fit it, will be returned. It's easy to see the difference between find and filter when we use the same condition on both, and the result is different.

```js
const  characters  =  require('../characters-data/characters');

const  result  =  characters.find((cur) =>  cur.name.includes('White'));

console.log(result);
 /*
 {
	 char_id: 1,
	 name: 'Walter White',
	 birthday: '09-07-1958',
	 occupation: [ 'High School Chemistry Teacher', 'Meth King Pin' ],
	 img: 'https://images.amcnetworks.com/amc.com/wp-content/uploads/2015/04/cast_bb_700x1000_walter-white-lg.jpg',
	 status: 'Presumed dead',
	 nickname: 'Heisenberg',
	 appearance: [ 1, 2, 3, 4, 5 ],
	 portrayed: 'Bryan Cranston',
	 category: 'Breaking Bad',
	 better_call_saul_appearance: []
}
 */
```

When none of the elements fit the condition, the function returns **`undefined`**.

```js
const  characters  =  require('../characters-data/characters');

const  result  =  characters.find((cur) =>  cur.name.includes('Bla Bla Bla'));

console.log(result); // undefined
```

### `.some()`
Different from the previous functions, some will return **`true`** or **`false`**. The response will depend if at least **_one element_** satisfies the condition used.
```js
const  characters  =  require('../characters-data/characters');

const  result  =  characters.some((cur) =>  cur.nickname  ===  'Heisenberg');

console.log(result); // true
```

### `.every()`
Even as the some function, it returns **`true`** or **`false`**. The difference's **_all_** the elements have to correspond to the condition to return true.

```js
const  characters  =  require('../characters-data/characters');

const  result  =  characters.every((cur) =>  cur.nickname  ===  'Heisenberg');

console.log(result); // false
```

### `.reduce()`
This function receives a different set of parameters. 
- **First param:** the accumulator where a number is stored.
-  **Second**, **third**, and **fourth** are in the same sequence as shown before. 

We use this function to calculate something present in all elements. In the example, we use it to calculate how many characters are in the Breaking Bad show. 

```js
const  characters  =  require('../characters-data/characters');

const  howUseIt  =  characters.reduce((acc, _curr, id, _array) => {
	console.log(`There is ${acc} accumulated, we are at position ${id}`);
	return  acc  +  1
}, 0);

/*
There is 0 accumulated, we are at position 0
There is 1 accumulated, we are at position 1
There is 2 accumulated, we are at position 2
...
There is 61 accumulated, we are at position 61
*/

console.log('There are '  +  howUseIt  +  ' characters on the show');
// There are 62 characters on the show
```

You can notice that after the callback, there is a zero. This number is the **initial number** used as our accumulator. In the second example, we can see what happens if this number is 10.

```js
const  characters  =  require('../characters-data/characters');

const  result2  =  characters.reduce((acc) =>  acc  +  1, 10);

console.log(result2); // 72
```

### `.sort()`
For this function, I had great help from a friend that studies with me, [Arthur Coelho](https://www.linkedin.com/in/arthurccoelho/). He gave me several tips about how it works and suggested how to sort an array randomly using this function.

We use this function when we need to sort an array according to a rule. The most different feature present in this function is that it **changes the original array**. 

```js
const  myArray  = [90, 78, 65, 54, 09, 45, 35];

console.log(myArray); // [ 90, 78, 65, 54 ]

const  sorting  =  myArray.sort(() =>  Math.random() >  0.5  ?  -1  :  1);

console.log('sorting: ', sorting ); // sorting: [ 54, 78, 90, 65 ]
console.log(myArray); // [ 54, 78, 90, 65 ]
```
> **How to sort an array randomly:** We use the **`Math.random`** function. It returns a random number between 0 and 1. We just need to use a ternary operator to determine the return.

The function sort, just like the reduce, works with different parameters.
- **First param:** the current element.
-  **Second param:** the next element.

We must create a conditional that returns a number. If it returns a **negative** number the sequence **stays the same**. If it returns a **positive** number the **order will change**, where the first param and the second one will switch places. By convention, we usually use the numbers 1 and -1.

First, we have the sort by name. When we compare two strings, the one that is "bigger" actually is the one that is more close to the end of the alphabet. So if we want it in alphabetic order, we should switch the place of the words (return a positive number).

```js
const  characters  =  require('../characters-data/characters');

const  result  =  characters.sort((a, b) =>  a.name  <  b.name  ?  -1  :  1);

console.log(result);
/*
[
	{
		char_id: 31,
		name: 'Adam Pinkman',
		...
	},
	{
		char_id: 23,
		name: 'Andrea Cantillo',
		...
	},
	...
	{
		char_id: 4,
		name: 'Walter White Jr.',
		...
	},
	{
		char_id: 36,
		name: 'Wendy S.',
		...
	}
]
*/
```

Now, sorting numbers is easier than words, since if we return a subtraction between them, we already return a positive or negative number.

```js
const  characters  =  require('../characters-data/characters');

// If we want a crescent order we use 'a - b'
// If we want a descending order we use 'b - a'
const  result  =  characters.sort((a, b) =>  a.char_id  -  b.char_id);

console.log(result);

/*
[
	{
		char_id: 1,
		...
	},
	{
		char_id: 2,
		...
	},
	{
		char_id: 3,
		...
	},
	...
]
*/
```

---
If you see something that can be improved, please contact me! All feedback is very welcome.:sparkles:
<div align='center'>
<a href="mailto:maybsalvalaio@gmail.com"><img alt="logo-mail" src="https://img.shields.io/badge/-Gmail-%23333?style=for-the-badge&logo=gmail&logoColor=white" /></a> <a href="https://www.linkedin.com/in/maysa-b-salvalaio" rel="noreferrer" target="_blank"><img alt="logo-linkedin" src="https://img.shields.io/badge/-LinkedIn-%230077B5?style=for-the-badge&logo=linkedin&logoColor=white" /></a> <a href="https://github.com/Maysa-B" rel="noreferrer" target="_blank"><img alt="logo-git" src="https://img.shields.io/badge/-GitHub-311c39?style=for-the-badge&logo=Github&logoColor=ffffff&" /></a>
</div>