DEV Community

loading...

Higher Order Functions with Reduce

_mohanmurali profile image Mohan Murali ・5 min read

Yesterday in one of the discord servers we were discussing about Higher Order Functions. Reduce being one of my Favourite higher order functions in javascript array object, I have tried to recreate other commonly used higher order functions using reduce just for fun (also i did not find any such existing implementation examples in one post). In this blog, I will re-create the following higher order functions of the array object using reduce.

  1. Map
  2. Filter
  3. Find
  4. Every
  5. Some

I will be using simple examples to make it easier to understand. So lets get started!

Map

The map() method creates a new array populated with the results of calling a provided function on every element in the calling array.

We can use map function to perform some operation on each element in the array. In the below example, we will be using map to square each element in the array.

let sampleArray = [1,2,3,4,5,6,7,8,9,10];

let mapResult = sampleArray.map(current=> current * current);
Enter fullscreen mode Exit fullscreen mode

If we try to log the result we will get the following result.

[1,  4,  9,  16,  25,  36,  49,  64,  81,  100]
Enter fullscreen mode Exit fullscreen mode

Now lets implement the same functionality using reduce.

let reduceResult = sampleArray.reduce((acc, curr)=> [...acc, curr * curr], []);
Enter fullscreen mode Exit fullscreen mode

If you log the result, you will see that you get the same result. Now lets move on to filter.

Filter

The filter() method creates a new array with all elements that pass the test implemented by the provided function.

We can use the filter() function to remove the unwanted elements from the array. Basically filter takes a callback function which returns a boolean value. This callback function is called on each element of the array. Which ever element returns false for the callback function will be removed from the resulting array.

In the below example, from an array of numbers 1-10, I will be removing the elements which are less then five using filter function.

let sampleArray = [1,2,3,4,5,6,7,8,9,10];

let filteredArray = sampleArray.filter(current=>current > 5)
Enter fullscreen mode Exit fullscreen mode

If we log this we will get the below result.

[6,  7,  8,  9,  10]
Enter fullscreen mode Exit fullscreen mode

With reduce, the same functionality can be achieved with a little bit more lines of code.

let reducedFilterArray = sampleArray.reduce((acc, curr)=> {
  if(curr > 5){
    return [...acc, curr];
  } else 
    return acc;
},[]);
Enter fullscreen mode Exit fullscreen mode

The result will be same as the one with filter() function.

So far, filter and map have been pretty simple to implement with reduce with only few extra lines of code. Now lets look into more complex functions starting with find.

Find

The find() method returns the value of the first element in the provided array that satisfies the provided testing function. If no values satisfies the testing function, undefined is returned.

find() method takes a callback function and and executes the function on each element of the array. If it finds the element that satisfies the callback function it returns the element and stops the execution. As the name suggests, this method is used to find a element. If it does not find any elements to satisfy the condition it will return undefined. Lets look at an example.

let sampleArray = [1,2,3,4,5,6,7,8,9,10];

let findResult = sampleArray.find(current => current > 5);
Enter fullscreen mode Exit fullscreen mode

So in this example, we are going to find the first element that is greater then five. Lets log to see the result of the function. If you thought 6 then congratulations, you are right!

6
Enter fullscreen mode Exit fullscreen mode

So there are two things that find() does essentially, first is to return the first element that satisfies the condition and the second is to return undefined if none of the elements satisfies the condition. Now the problem when we try to implement this with reduce is that reduce takes effect on each element in the array and there is no way to stop it once the first elment is found. So, I used my big brains and came up with the following solution to this problem

let reduceResult = sampleArray.reduce((acc, curr)=> {
  if(curr > 5) {
    if(acc){
      return acc;
    } else {
      return curr;
    }
  } else {
    return undefined
  }
}, undefined);
Enter fullscreen mode Exit fullscreen mode

Let me walk you through the solution here. First of all, I am setting the inital object to undefined so that if we use it on an empty array we will get the same result as find. Second, I am using a condition to return the result, the condition being if there is some value in the result we will not assign any other value to it. This is to prevent the next values passing the condition to overwrite the first matching value. Now if you log this result you will see that the results are same as that of find.

Every

The every() method tests whether all elements in the array pass the test implemented by the provided function. It returns a Boolean value.

every() method returns true if every element in the array satisfies the callback function, otherwise it returns false. So even if a single element does not match the condition, it will return false. Typically we will use every() to validate some data. In the below example I am having 2 data sets and i am checking if all the elements in my array are less then 11.

let sample1Array = [1,2,3,4,5,6,7,8,9,10];
let sample2Array = [2,5,7,9,11,13,15];

let everyTrue = sample1Array.every(current=> current < 11);
let everyFalse = sample2Array.every(current=> current < 11);
Enter fullscreen mode Exit fullscreen mode

For this example the sample1Array will return the result as true and sample2Array will return false.

sample1Array -> true
sample2Array -> false
Enter fullscreen mode Exit fullscreen mode

So how do we implement this with reduce? Big brain time again! By using the learnings of the previous 3 methods i was able to achieve this with the below code.

let reduceTrue = sample1Array.reduce((acc, curr)=> { 
  if(curr < 11){
    return true
  } else 
    return false
}, true);

let reduceFalse = sample2Array.reduce((acc, curr)=> { 
  if(curr < 11){
    return true
  } else 
    return false
}, true);
Enter fullscreen mode Exit fullscreen mode

I will not walk through this code as its pretty similar to what we did with find().

Some

The some() method tests whether at least one element in the array passes the test implemented by the provided function. It returns a Boolean value.

some() is kind of opposite of what every() is in the sense if returns true if any element in the array satisfies the condition of the callback function and false only if none of the elment satisfy. For this example, I am reversing the condition of the example i used for every().

let sample1Array = [1,2,3,4,5,6,7,8,9,10];
let sample2Array = [2,5,7,9,11]

let someFalse = sample1Array.some(current=> current > 10);
let someTrue = sample2Array.some(current=> current > 10);
Enter fullscreen mode Exit fullscreen mode

So here, we will get the result of sample1Array as false and sample2Array as true. So the implementation for this using reduce will also be very similar to what we have done with every() with slight changes.

let reduceFalse = sample1Array.reduce((acc, curr)=> {
  if(curr > 10){
    return true;
  } else 
    return acc;
}, false);

let reduceTrue = sample2Array.reduce((acc, curr)=> {
  if(curr > 10){
    return true;
  } else 
    return acc;
}, false);
Enter fullscreen mode Exit fullscreen mode

If we log the results we will see that results for both the functions are same.

sample1Array -> false
sample2Array -> true
Enter fullscreen mode Exit fullscreen mode

Conclusion

First of all, if you guys are still here then a big thanks to all of you. This blog turned out to be longer then I expected. Also, there is no real conclusion here, just wanted to show the power of reduce. Now if you ask me should I use reduce for every situation, the answer will be a big NO. But its handy to know that if we want, we can do all this with reduce.

Last thing I would like to say is the definition of all the functions have been taken from MDN. Its a great site for more information on all the functions and web in general.

Discussion (7)

pic
Editor guide
Collapse
angelomiranda profile image
angelo.miranda

I appreciate the effort Mohan! A lot of people would definitely find this post very helpful. I see how much time you spent you on this post and definitely deserves a thumbs up!

Reduce is one of my favorite array method as well. As a matter of fact, I made a video of it on youtube about a week ago, here is the link in case you are interested to see. I am working on filter and then map soon.

btw, I see small typos on Function.

Collapse
_mohanmurali profile image
Mohan Murali Author

Oh my bad, was always bad with spellings :). Thanks for the feedback. Good thing you shared your video link here cause one thing i have not done here is explain about reduce which you have done beautifully :).

Collapse
angelomiranda profile image
angelo.miranda

no problem. thanks for the kind words. i’m looking forward on your next post. 👊

Collapse
amansethi00 profile image
Aman Sethi

Great explanation Mohan ,yesterday when you said reduce can be used to implement filter,map,find and other higher order array functions I gave my thought of how can it be done but couldn't figure by myself but now I feel confident.

Thank you buddy :)

Collapse
_mohanmurali profile image
Mohan Murali Author

Thanks, next time we will have a proof :)

Collapse
realtoughcandy profile image
RealToughCandy.io

Nice post. Good explanation of find ().

Collapse
_mohanmurali profile image
Mohan Murali Author

Thanks mam! I am so excited! You have been an inspiration for me.