Functional Programming in JavaScript

The Javascript support multiple programming paradigms like object-oriented and functional paradigms. , The most of the javascript libraries are multiple programming paradigms. However, JQuery has a strong flavor of functional programming, while Ext.js is a completely object-oriented javascript library.

In this section, we will be learning most important predefine function in the JavaScript to perform an operation like (map, filter, reduce ) on collection or an array.

Functional programming provides developers with the tools to abstract common collection operations into reusable, composable building blocks.  The most of the operations we perform on collections can be accomplished with five simple functions (some native to JavaScript and some included in the RxJS library):

  1. map
  2. filter
  3. concatAll
  4. reduce
  5. zip

We will be learning the map, filter and reduce functions.

  1. Map: The 
    <strong>map()</strong>

     method creates a new array with the results of calling a provided function on every element in the calling  or existing array. We have to supply array, runs that through a function (which can be used to perform certain operations on the supplied array – such as, for example, converting each array item value to upper case) and subsequently returns a new array once completed.

    var numbers = [1, 4, 6, 10];
    var doubles = numbers.map(function(x) {
       return x * 2;
    });
    // doubles is now [2, 8, 12, 20]
    // numbers is still [1, 4, 6, 10]
    
    //ES6 example
    
    const numbers = [2, 14, 18, 22];
    const halves = numbers.map(x => x / 2);
    // halves is now [1, 7, 9, 11]
    // numbers is still [2, 14, 18, 22]
    
    var numbers = [1, 4, 9];
    var roots = numbers.map(Math.sqrt);
    // roots is now [1, 2, 3]
    // numbers is still [1, 4, 9]

In the second example, we are creating a new array to containing only countries name from existing array as follow.

var newArr = [
{ id: 1, country: "England" },
{ id: 2, country: "Scotland" },
{ id: 3, country: "Wales" },
{ id: 4, country: "Northern Ireland" },
{ id: 5, country: "Republic of Ireland" },
{ id: 6, country: "France" },
{ id: 7, country: "Germany" },
{ id: 8, country: "Italy" },
{ id: 9, country: "Spain" },
{ id: 10, country: "Belgium" },
{ id: 11, country: "Holland" },
{ id: 12, country: "Czech Republic" }
];
// New Array with only countries list
countries = newArr.map(function(x) {
    return x.country
});

console.dir(countries);

 

Filter: The method

filter()

creates a new array with all elements that pass the test implemented by the provided function.

Syntax : var newArray = arr.filter(callback[, thisArg])

When using the map method to create new arrays every value from the original array is mapped to the new array. As useful as this is there are times when you only want to retrieve specific values from an array. Using the filter method values can be retrieved if they meet specific criteria. Let’s take our previous example and use the filter method to only return every 4th item from the associative array:

var newArr = [
{ id: 1, country: "England" },
{ id: 2, country: "Scotland" },
{ id: 3, country: "Wales" },
{ id: 4, country: "Northern Ireland" },
{ id: 5, country: "Republic of Ireland" },
{ id: 6, country: "France" },
{ id: 7, country: "Germany" },
{ id: 8, country: "Italy" },
{ id: 9, country: "Spain" },
{ id: 10, country: "Belgium" },
{ id: 11, country: "Holland" },
{ id: 12, country: "Czech Republic" }
];
var countries = newArr.filter(function(x){
if(x.id % 4 === 0) {
    return x;
}
});
console.dir(countries);

// Outputs following to web console

[{id: 4, country: “Northern Ireland”},
{id: 8, country: “Italy”},
{id: 12, country: “Czech Republic”}]

Second example

const words = ["spray", "limit", "elite", "exuberant", "destruction", "present", "happy"];

let longWords = words.filter(word => word.length > 6);

// Filtered array longWords is ["exuberant", "destruction", "present"]

In the third example, we can also combine the filter and map methods for the above examples so we end up with an array populated solely with the names of every 4th company like so:

var existArr = [
{ id: 1, company: "EMC" },
{ id: 2, company: "Google" },
{ id: 3, company: "Facebook" },
{ id: 4, company: "Apple" },
{ id: 5, company: "Infosys" },
{ id: 6, company: "HLC" },
{ id: 7, company: "HP" },
{ id: 8, company: "Wipro" },
{ id: 9, company: "IBM" },
{ id: 10, company: "Paypal" },
{ id: 11, company: "Yahoo" },
{ id: 12, company: "Microsoft" }
],

companies = newArr.filter(function(x){
    if(x.id % 4 === 0){
        return x;
    }
    })
    .map(function(x){
        return x.company
    });
    console.dir(companies);
// Outputs following to web console

[“Apple”, “Wipro”, “Microsoft”]

 

Reduce(): The reduce() method applies a function to an accumulator and each element in the array (from left to right) to reduce it to a single value.   Syntax :

arr.reduce(callback[, initialValue])

The reduce method accepts two parameters; first is the callback function, which is applied to each element of the array, and the second one is the initial value of the accumulator.

The reduce executes the callback function once for each element present in the array, excluding holes in the array, receiving four arguments: accumulator, currentValue, currentIndex and array. accumulator

The accumulator accumulates the callback’s return values; it is the accumulated value previously returned in the last invocation of the callback, or initialValue, if supplied (see below).

The currentValue: The current element being processed in the array.

The currentIndex :  The index of the current element being processed in the array. Starts at index 0, if an initialValue is provided, and at index 1 otherwise.

The array:  The array reduce was called upon.

Example one: simple reduce function to calculate the sum of all the array element.

const total = [0, 2, 4, 6].reduce(function(sum, value) {
  return sum + value;
}, 1);
// total is 12


// ES6 version

const total = [0, 2, 4, 6].reduce((sum, value) => sum + value, 1);
// total is 12

var flattened = [[0, 1], [2, 3], [4, 5]].reduce(function(a, b) {
  return a.concat(b);
}, []);
// flattened is [0, 1, 2, 3, 4, 5]


// ES6 version
const flattened = [[0, 1], [2, 3], [4, 5]].reduce((a, b) => a.concat(b), []);
// flattened is [0, 1, 2, 3, 4, 5]

 

Example 2: Here we are using most of the callback argument, where html argument is an accumulator, the task is existing an array where we are performing reduce function and index is an index of task array.

class ToDoClass {
    constructor() {
      this.tasks = JSON.parse(localStorage.getItem('TASKS'));
      if(!this.tasks) {
        this.tasks = [
          {task: 'Morning yoga', isComplete: false},
          {task: 'Do Exercise', isComplete: true},
          {task: 'Renew Bank Account', isComplete: false},
        ];
      }
      this.loadTasks();
    }

    loadTasks() {
      localStorage.setItem('TASKS', JSON.stringify(this.tasks));
      let tasksHtml = this.tasks.reduce((html, task, index) => html += this.generateTaskHtml(task, index), '');
      document.getElementById('taskList').innerHTML = tasksHtml;
    }
	
	 generateTaskHtml(task, index) {
      return `
		..............
      `;
	}
}

window.addEventListener("load", () => {
  toDo = new ToDoClass();
});