Recreating Array Methods Using Reduce
Published: 2020-11-09 13:58:19

######Skills that are included in this article: Array Methods, Callback Functions, Spread Operator

We are going to rewrite a few array methods using Reduce to better understand not just the way reduce works, but also the way the original methods work. 

####What is a reducer?
A reducer function is a pure function that takes in a state, the accumulator. It then mutates the state with a provided function and returns the new mutated state. This is why almost every basic example of the reduce method uses addition, you take in a state (the number 0) and you mutate it by adding numbers from the array you called this method on to it. The accumulator will always be the exact value that was most recently returned. It can be any type of value. 
 
So, why is rewriting code that already works, and works much more efficiently, a good idea? It’s not. Well not for the purposes of including in any code you may be writing. It is a good idea however, because it helps to better understand what reduce is doing. It will also help reframe the way you think about more common array methods.

####The Tools We Have
So, first, let’s examine the tools we have before us. 
We are going to be writing these functions so that they take in two arguments, (1)the array we want to mutate and (2)the function that will do the mutating. 

The reduce method has 2 arguments, a required callback function (called the reducer) and an optional initial value. If the initial value is not passed, the initial value is instead the first element in the array. I generally always pass an initial value, as not doing so will cause the function to not run on the first element.

The callback function has 4 arguments, an accumulator, the current element being processed, the current element’s index and finally the original array.

###The Basics
This is going to be our basic setup. As you can see, we are passing in an array (arr) and a function.

![The Basic Function](https://dev-to-uploads.s3.amazonaws.com/i/3qiita3nd01uup7kxccq.png)
The function returns the array immediately, calling the reduce method with a callback function and an undefined initial value. Going forward, the only changes to this setup are going to be the reducer function and the initial value. 

###For Each
The forEach method executes a function for each element in an array. It always returns undefined. 
![ForEach Function Using Array.reduce](https://dev-to-uploads.s3.amazonaws.com/i/t1tcffwe9bam2dwlv2x3.png)


First looking at the result, we will not need to make a change to our accumulator. Next, in our reduce array, we define our callback function that consumes the accumulator, current value and the current index.  These arguments are immediately passed to our reducerFunction callback. The forEach method passes the current value, the current index and finally the original array back to the callback function. We don’t need to return anything as the expected return value is undefined. 

And that’s it for forEach. Reduce is going to run the arrayFunction callback at each element of the array and the arguments have been passed down in the same order as the original forEach method. Next we will work on returning a value using the accumulator.

###Some and Every

The Some method returns true if the callback returns true at least once, otherwise it returns false.

The Every method returns trues if the callback returns true for every element in the array, otherwise it returns false.
![Some and Every Functions Using Array.reduce](https://dev-to-uploads.s3.amazonaws.com/i/wz3m6ve24iraw6g98wf9.png)

I have grouped these two methods as their goal is essentially the same. These methods parse through an array of objects and return a Boolean value based on the outcomes of the callback function. For both of these methods the callback is expected to be a Boolean value. That said, there is one major issue with using reduce to emulate these methods. The original methods immediately return once the value has been flipped, this reduce does not. In general it is not recommended to break a reduce and is not a part of its design.

First, let’s go ahead and set the initial value for the Some function to false. We are setting this to false as it is the default outcome for this function. If nothing is true then we will return automatically false. Next in our Some function, we will pass a callback to receive the accumulator, currentValue and index from reduce. Then we will create an if statement  that checks the value returned from the reducerFunction. If that is true we will return true, if not we will return whatever the current accumulator is, false if it has never been changed, true if it has. In this way we are updating the accumulator at each step, while the value isn't always changing, the accumulator actually is taking in a new value at each element. Every is created using the exact same logic, but reversed. We are defaulting to true and checking if any are not true. 

So now that we are running a function at each element and updating our accumulator at each step we will move on to some more advanced tasks.

###Map
The Map method executes a function for each element in an array and creates a new array where each element is the result of the executed function.

![Map Function Using Array.reduce](https://dev-to-uploads.s3.amazonaws.com/i/2vbrgbv26ru8idcfts6o.png)

First, we are going to have a complex data type for our initial value, an array. We are going to be consuming this array and adding on to it at each step. Much like the forEach function there is no Boolean logic at play in our reduce method. To replicate the map at each element we will create then return a new array. First, the accumulator is spread, finally the result of the reducer function is passed as the final element. The newly returned array will become the new accumulator state, set to be spread and returned at the next element.

###Filter
The Filter method executes a function for each element in an array, if the function returns true the element is added to a new array that is returned.

![Filter Function Using Array.reduce](https://dev-to-uploads.s3.amazonaws.com/i/lnhymht07cyptwt2w10t.png)

This is going to bring together everything so far. We will execute a function for each element in the array and check if the value is truthy or not. We will then return, not the result, but the original element itself along with all elements already returned. 

As with the Some function, we start with an if statement, and return the current accumulator if that statement is not true. However if that function returns true we will spread the current accumulator and add the currentValue as the last item in that array. 


###Final Thoughts
So that is it. The reducer method is fairly powerful in that you have a large amount of control on both what the is doing at each element and what it is returning. We can loop through arrays and return nothing, return a primitive data type determined by any element in the array, or return a more complex data type.