# JavaScript array functional methods

Close look at functional methods that JavaScript arrays provide.

Let us define functional methods from an array perspective as those methods that let you write code that you typically write using iterators/for loops without using them.

These methods take in

a) a function as argument and

b) also dictates what the first few parameters of those functions indicates.

In the argument function, following are the parameters.

1)The first parameter typically stands for the array element.

2)The second element where applicable indicates the index.

3)The third parameter where applicable indicates the array itself.

These functional array methods also dictate what kind of return value these parameter functions are supposed to return. For instance, the map method is supposed to take in a function that returns the value that the current element in the array is to be replaced with, the every method is to return a function that returns a boolean value. Also, for each of these functional methods, the

parameter functions can either be predefined functions or be anonymous functions.

These are the kinds of functional functions.

1)Methods that operate on every element of the array.forEach: Perform specific action for each element in the array.

Input: Array element

Ouput: Nothing. Does not return anything. Just performs actions using the array element.

> var pushDouble = function ( number ) {

… resultArray.push(number * 2) ;

… };

undefined

> arr

[ 1, 2, 3, 4, 5 ]

> resultArray

[]

> arr.forEach(pushDouble);

undefined

> resultArray

[ 2, 4, 6, 8, 10 ]

2) **Methods to map or replace the current element in the array with it’s new value**

Input: Element, Index of the element, the array itself

Output: Changed value corresponding to the element.**map**: Accepts a function that is applied to each element of the array.

The function has the array element as the first parameter.

Can also take the index as the second parameter

and the array itself as the third parameter.

The function being passed can be a separately defined function.

The function being passed can also be an anonymous function defined then and there.The original array is left untouched.

Returns an array with the mapped value got by applying the function

on to each element.

Anonymous function that works only using the element

> var arr = [1,2,3];

undefined

> arr.map(function(element){return element*2;});

[ 2, 4, 6 ]

Anonymous function that works using the element and the index position of the element. In this example, it serves to double only the elements at odd indices.

> arr.map(function(element,index){

… if(index%2===1){

….. return element * 2;

….. } else {

….. return element;

….. }

… });

[ 1, 4, 3 ]

Anonymous function that works using the array,the index and the element as arguments.

> arr.map(function(element,index,array){

… return element * index * array.length;

… });

[ 0, 6, 18 ]

What happens if the function is designed to act only on certain elements and the remaining elements are untouched, would the original elements be retained?

No it would not be. The reason is that the map function returns a new array.

So for indices for which the mapping function does not define a mapping would get the value undefined.

> arr.map(function(element,index){if(index%2===1){return element * 2; }});

[ undefined, 4, undefined ]

3) **Methods to check something about the array**. **some**: Checks if there are some elements in the array that satisfy the condition being checked by the argument function.

Argument function specifics

Input:element

Output:boolean value indicating the result of the check on the particular element.

> arr

[ 1, 2, 3, 4, 5 ]

> arr.some(function(element){return element > 4;});

true

**every**: Checks if every element in the array satisfies the condition being checked by the argument function.

Argument function specifics

Input: element

Output: boolean value indicating the result of the check that needs to be done on the element.

4) **Methods to do aggregation over the elements in the array**. **reduce**:Does an aggregation operation across all the elements of the array by applying an operation on the first two elements and using that result and the third element to get the next value and so on till the end of the array. Does left to right aggregation.

Argument function specifics

Input: leftElement,rightElement

Output: Result of the computation/logic applied.

> arr

[ 1, 2, 3, 4, 5 ]

> arr.reduce(function(n1,n2){return n1+n2;});

15

The technique here is that the developer just needs to focus on the complexity of dealing with two arguments and the reduce function takes care of applying it across the array.

**reduceRight**: Similar to reduce function except that the cumulating operation is done from right to left instead of from left to right.

For commutative operations like addition and multiplication, the result for an array of numbers would be the same for reduce as well as reduceRight. However, for non-commutative operations like division and subtraction, this is not the case.

> arr

[ 1, 2, 3, 4, 5 ]

> arr.reduce(function(n1,n2){return n1+n2;});

15

> arr.reduceRight(function(n1,n2){return n1+n2;});

15

> arr

[ 1, 2, 3, 4, 5 ]

> arr.reduce(function(n1,n2){return n1 — n2;});

-13

> arr.reduceRight(function(n1,n2){return n1-n2;});

-5

5)** Methods to filter elements from an array based on some condition**.**filter**: Filters from an array only the elements that satisfy the condition captured in the argument function.

Argument function specifics

Input: element

Output: boolean indicating whether the current element satisfies the filter condition.

> arr

[ 1, 2, 3, 4, 5 ]

> arr.filter(function(n){return n>3;});

[ 4, 5 ]

**find**: Finds the first element in the array that satisfies the condition captured in the argument function.

Argument function specifics

Input: element

Output: boolean indicating whether the current element satisfies the filter condition.

> arr

[ 1, 2, 3, 4, 5 ]

> arr.find(function(element){

… return element > 3;

… });

4

Let us see what happens when a boolean returning function is passed to each

of the functional methods.

> arr

[ 1, 2, 3, 4, 5 ]

> var more = function ( number ) {

… return number > 3;

… };

undefined

> arr

[ 1, 2, 3, 4, 5 ]

> arr.filter(more);

[ 4, 5 ]

Filters out numbers satisfying more.

> arr.find(more);

4

Finds the first element satisfying more.

> arr.some(more);

true

Checks if there are some elements satisfying more.

> arr.every(more);

false

Checks if every element satisfies more.

> arr.map(more);

[ false, false, false, true, true ]

Maps each element to the boolean indicating whether it satisfies more or not.

> arr.reduce(more);

false

Don’t think this is really applicable.

> arr.reduceRight(more);

false

Don’t think this is really applicable.

Let us look at how the behavior is when you apply a function that returns a changed value.

> arr

[ 1, 2, 3, 4, 5 ]

> var double = function ( n ) {

… return n*2;

… };

undefined

> arr.map(double);

[ 2, 4, 6, 8, 10 ]

> arr.reduce(double);

16

> arr.reduceRight(double);

80

In case of reduce and reduceRight where typically two parameters are used, single parameter function would also work just as well by applying that one argument on the function. Meaning essentially reduce takes the first element and doubles it and then doubles the result of that and so on till the array is traversed left to right and reduce right takes the last element and doubles it and keeps doubling it at every step till it reaches the start of the array. So, the only thing that matters is what the first element is and the number of elements is in the case of reduce and what the last element is and the number of elements is in the case of reduceRight.

Illustrated below.

> var double = function ( n) { return n*2; }

undefined

> var arr = [1,234,28377,454,5];

undefined

> arr.reduce(double);

16

> arr.reduceRight(double);

80

>