Skip to content
loading...

The Power of Higher Order Functions in JavaScript (With examples and use cases)

jsmanifest on September 20, 2019

Find me on medium JavaScript utilizes functions in just about every JavaScript application that exists. Thanks to functions, the language is capab... [Read Full]
markdown guide
 

i also suggest a re write to this functionality of the last pass


filterMaleFrogs = function (frog) {
   return frog.gender === 'Male'
};

filterAdultFrogs = function (frog) {
   return frog.age >= 10
};

filterFrogNamesThatStartWithHippo = function (frog) {
   return frog.name.toLowerCase().startsWith('hippo')
};

filterGmailEmails = function (frog) {
   return /gmail.com/i.test(frog.email)
};

function composeFrogFilterersModified(...fns) {

   return function (frogs) {
      return frogs.filter(
         combineFilters(fns)
      );
   }
}

function combineFilters(fns) {
   return function (frog) {
      return fns.reduce(function (accumulatedFilter, currentFilter) {
         if(accumulatedFilter === false) {
            return false;
         }

         return !!currentFilter(frog);

      }, true);
   }
}

const applyFrogFilterersComposedAgain = composeFrogFilterersModified(
   filterMaleFrogs,
   filterAdultFrogs,
   filterFrogNamesThatStartWithHippo,
   filterGmailEmails,
);

const allFilteredFrogsModified = applyFrogFilterersComposedAgain(combinedFrogsList);
console.log('all filtered frogs: ', allFilteredFrogsModified);

from my understanding, this will only go once per frog and not create array.filter 4 times
please correct me if iam wrong or missed something on your implementation

 

Hi SerjoA, thank you for the suggestion and the workaround!

I will edit the post and swap out the current code example with the example you provided because its correct.

I'm going to make a slight modification to your combineFilters function to run this instead:

function combineFilters(...fns) {
   return function (frog) {
     for (let i = 0; i < fns.length; i++) {
       const filter = fns[i]
       const passes = filter(frog)
       if (passes) {
         continue
       } else {
         return false
       }
     }
     return true
   }
}

This is a slightly more optimized version which reduces the amount of iterations as much as possible.

Thank you!

 
 

I love the use of reduce with collections of functions!
+1 @serjoa 🦄

 

can you please explain how composeFrogFilterers is not creating the line:
return frogs.filter(filter)

from the filterFrogs function

while the above function :
applyAllFilters
does create this line 4 times instead of 1 like you mention?
from the logs i did, both run 4 times not just one
can you please say where iam wrong:

inside applyAllFilters:

for (let index = 0; index < filters.length; index++) {
         const filter = filters[index];
         console.log('newfrogs leng: ', newFrogs.length);
         newFrogs = filter(newFrogs); // calling filter function on new frogs array.filter
      }

inside composeFrogFilters:

return fns.reduce(function(accumulatedFrogs, fn) {
         console.log('leng of acc frogs: ', accumulatedFrogs.length);
         return fn(accumulatedFrogs) // also calling frogs array.filter with the fn as filter func
      }, frogs)

 

You are right, both of the examples both re-create the arrays. Will edit the post with the correct solution (check my response to your other reply for the solution)

 

It's really useful to see the logic and workings, thanks. I've been increasingly developing with a functional approach and find it quite liberating. You only find out how and why by trying it out and learning by doing.

For a really simple solution in this case could you use the Ramda ap function? ramdajs.com/0.19.1/docs/#ap

 

Hey there! I shared your article here t.me/theprogrammersclub and check out the group if you haven't already!

 
code of conduct - report abuse