Higher-Order Functions

Higher-Order Functions

Functions that operate on other functions, either by taking them as arguments or by returning them, are called higher-order functions.

This is the main contrast to first-order functions. First-order functions DO NOT take functions either as arguments or returning them as output.

The main goal of having higher-order functions is abstraction, that is, hiding certain gritty details of problem-solving allowing developers to focus on a few concepts at a time.

For example: When using the .map() higher-order function, our focus is not on how the function iterates through each of the array elements and passing these elements to the callback function. This level of problem-solving is abstract/hidden from us. Our concern then goes to: given an array, how do we want to transform it, without worrying about the specifics of iterating through each of the elements.

Writing higher-order functions

Even though JavaScript already supports several higher-order functions. Writing our own higher-order functions is still required from time to time.

So, say we are to write our own version of map() function similar to what array.map() does:

function map(arr, func){    
    let newArr = [];

    for(let i=0; i<arr.length; i++){    
        newElem = func(arr[i]);    
        newArr.push(newElem);
    }

    return newArr;
    }

let test = map([1, 2, 3],(val) => {return val * 2});
console.log(test);  /* [2, 4, 6] */

Explanation of the map() function code above:

  • function map(arr, func) takes two arguments: the array to be modified (arr) and the function that modifies each of the array elements (func).

  • newArr is the modified array that will be returned by map function.

  • using for loop, we iterate through each of the arr elements.
  • Each arr element is passed to the callback function which modifies the specific element passed to it and returns it to the variable named newElem.
  • Now newElem is the modified new element returned by the callback function, and this value is then pushed to the newArr.
  • And finally the map function returns newArr.

.map(), .filter(), .reduce()

.map .filter .reduce are some examples of higher-order functions supported by JavaScript

a. Transforming Arrays with .map()

.map() method transforms an array by putting each element through a given callback function.

syntax: array.map( callback( currentValue, currentIndex, array));

.map() method returns a 'new' array with the results of the callback function applied to every element of the original array, in the same order.

b. Filtering Arrays with .filter()

.filter() method returns a 'new' array containing only the elements that pass the condition specified in the given callback function.

syntax: array.filter( callback( currentValue, currentIndex, array));

c. Summarizing with .reduce()

.reduce method reduces/ summarizes the whole array into a single value. It does this by repeatedly taking the currentValue from the array and combining it with the accumulator.

syntax: array.reduce ( callback( accumulator, currentValue, currentIndex, array));

The code below, illustrates the use of .map(), .filter() and .reduce():

const persons = [
    {name: 'Peter', birthYear: 1995},
    {name: 'Mark', birthYear: 1992 },
    {name: 'John', birthYear: 1991 },
    {name: 'Jane', birthYear: 2000 },
    {name: 'Tony', birthYear: 1990}
];
/*array.map
adds a third key-value pair-> age: 30, to each of the array elements.*/
persons.map(element => element.age = 2020 - element.birthYear);
console.log(persons);

/*array.filter
filters the elements with the property age less than or equal to 25*/
let persons_25 = persons.filter(element => element.age <= 25);
console.log(persons_25);

/*array.reduce
calculates the total age of persons. Sums the age property to a single value*/
let totalAge = persons.reduce((accumulator, element)=>accumulator + element.age, 0);
console.log(totalAge);

In conclusion, higher-order functions allow us to attain abstraction, hide the gritty details, and focus on a few essential concepts at a time.

Any comments and additions, would love to hear those.