Array methods and callback functions for beginners
Tags: javascript, arrays, callbacks, functional
Published: 2021-08-07 16:56:23

Callbacks functions and array methods can confuse some people when starting their journey as a developer. So let's reinforce our knowledge on Array methods and callbacks functions by breaking things down and going over some examples.

##Callback functions
First, we'll go over callback functions. A callback function is a `function` passed to another function as a parameter. 

```javascript
const add = (a,b) => {
  return a + b
}

function multiply(a,b) {
  return a*b
}

const solutionLogger = (a,b, callback) => {
  const solution = callback(a, b)
  console.log('the solution is ' + solution)
}

solutionLogger(2,4, add) //the solution is 6
solutionLogger(2,5, multiply) //the solution is 10
```

In the code above `add()` and `multiply()` would be our callback function. Both functions are provided to `solutionLogger()`. `solutionLogger()` then calls the callback function and logs out the solution. 

##Breaking down Array.map()

Suppose we had a list of numbers `[1,2,3]`. And we want to add `2` to each number in our list. For now, let's create a function to solve our problem without using any array methods. 

```javascript
function addTwo(numberList) {
  const newList = []
  for(let i = 0; i < numberList.length; i++) {
    const currentNumber = numberList[i]
    const updatedNumber = currentNumber + 2
    newList.push(updatedNumber)
  }
  return newList
}

addTwo([1,2,3]) // [3,4,5]
```

Our solution works great right now. But is there a way to make the solution more flexible? And instead of just limiting ourselves to running math operations on each number in the list, what if we could mutate each number in various other ways? Luckily we can... with callback functions!

```javascript
const addCallback = (number) => number + 2;

const multiplyCallback = (number) =>  number * 3;

const indexAndNumber = (number, index) => `${number} + ${index} = ${number + index}`

function mutate(numberList, callback) {
  const newList = []
  for(let index = 0; index < numberList.length; index++) {
    const currentNumber = numberList[index]
    const updatedNumber = callback(currentNumber, index)
    newList.push(updatedNumber)
  }
  return newList
}

const numberList = [1,2,3]

mutate(numberList, addCallback) // [ 3, 4, 5 ]
mutate(numberList, multiplyCallback) // [ 3, 6, 9 ]
mutate(numberList, indexAndNumber) 
//[
//  'index is 0 & number is 1',
//  'index is 1 & number is 2',
//  'index is 2 & number is 3'
//]
```

To better describe what our updated function does. We need to rename the function from `addTwo` to `mutate`. The two other minor changes we made to our `mutate` function were adding a `callback` parameter and using the callback's returned value to mutate each item in an array. We also provide the item's `value` and `index` to our callback.

I have also created three separate callback functions to test out the `mutate` function. `addCallback` and `multiplyCallback` are pretty straightforward; we run math operations on each item and return the new value. But what's more interesting is the `indexAndNumber` function. Not only does `indexAndNumber` uses the additional `index` parameter. But the function also changes the data type for all of the items in our array. Instead of having an `array` of numbers, we now have an `array` of strings.

###Anonymous callback functions
```javascript
function mutate(numberList, callback) {
  const newList = []
  for(let index = 0; index < numberList.length; index++) {
    const currentNumber = numberList[index]
    const updatedNumber = callback(currentNumber, index)
    newList.push(updatedNumber)
  }
  return newList
}

const numberList = [1,2,3]

mutate(numberList, (number, index) => {
  return `index is ${index} & number is ${number}`
})
// [
//   'index is 0 & number is 1',
//   'index is 1 & number is 2',
//   'index is 2 & number is 3'
// ]
```
In our previous example, we've stored one of the callback functions in a variable called `indexAndNumber`. But another way of obtaining the same results without declaring a new variable is by using an `anonymous` function. In the example above, we provide an `anonymous` function directly as a parameter to our `mutate` function. 

###Putting everything together
```javascript
function mutate(numberList, callback) {
  const newList = []
  for(let index = 0; index < numberList.length; index++) {
    const currentNumber = numberList[index]
    const updatedNumber = callback(currentNumber, index)
    newList.push(updatedNumber)
  }
  return newList
}

const numberList = [1,2,3]

mutate(numberList, (number, index) => {
  return `index is ${index} & number is ${number}`
})
// [
//   'index is 0 & number is 1',
//   'index is 1 & number is 2',
//   'index is 2 & number is 3'
// ]

numberList.map((number, index) => {
  return `index is ${index} & number is ${number}`
})
// [
//   'index is 0 & number is 1',
//   'index is 1 & number is 2',
//   'index is 2 & number is 3'
// ]
```
Finally, let's compare our solution `Array.map()`. We've created a function that mimics `Array.map()`. Like many other helper methods available for different data types, like `Arrays` or `Objects`. Helper methods basically allow us to manipulate our data while writing less code.

Thanks for reading! And I hope this breakdown was helpful.