Chris

Posted on

# Array methods and callback functions for beginners

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.

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.

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

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!

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

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

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.