# Higher Order Functions

## Abstraction

So what's exactly abstraction is? Let's understand.

Do you ever drive a car? In the case of a car, we know there is steering to change the directions, keyhole to start the car, etc. but you don't know the inner details of how it's working as a layman.

A similar case is when we directly use in-built functions like range, sum. We don't know how these all are working.

These in terms of programming called abstraction where we hide the details and gives the ability to see the functionality only and work with them.

## Abstracting Repetition

You can use the same function to do many things. Suppose there is a function that is console logging n numbers. It's simple.

``````function repeat(n)
{
for(let i=1; i<=n; i++)
{
console.log(i);
}
}
``````

But let's say we want to do something else with those n numbers rather than console logging we can modify.

``````function repeat(n, action)
{
for(let i=1; i<=n; i++)
{
action(i);
}
}
``````

We can do something with the functions too. As in JavaScript, they are also values. So we can pass action as the function value.

``````repeat(4, i => {
labels.push(`Unit \${i + 1}`);
});
``````

## Higher Order Functions

Functions that operate on other functions, either by taking them as arguments or by returning them. It allows us to abstract over actions. It comes in various forms.

• You can have functions that create new functions.
``````function greaterThan(n)
{
return m => m > n;
}

let greaterThan10 = greaterThan(10);
console.log(greaterThan10(11));
``````
• We can have functions that change other functions.
``````function noisy(f)
{
return (...args) => {
console.log("calling with ", args);
let result = f(...args);
console.log("calling with ", args, " returned", result);
return result;
};
}

noisy(Math.min)(3, 2, 1);
``````
• We can write functions that provide a new type of control flow.
``````function unless(test, then)
{
if(!test) then();
}

repeat(3, n => {
unless(n%2 === 1, () => {
console.log(n, "is even")
});
});
``````

There is a built-in array method forEach, that provides something like for loop as higher order function.

``````["A", "B"].forEach(l => console.log(l));
-> A
B
``````

## Filtering Arrays

filter() method creates a new array from the existing array, based on some condition.

``````const words=["spray", "limit", "elite", "destruction"];
const result = words.filter(word => word.length > 6);

consolee.log(result);
-> ["destruction"]
``````

In the above program, we are filtering the words whose length is greater than 6. filter method is taking one element at a time which we named as word and then we are checking the length of every word and returning the desired result.

It doesn't delete existing elements. It just creates a new array with the elements that meet the condition. So, if we print the `words` array it will give the same array.

``````console.log(words);
-> ["spray", "limit", "elite", "destruction"]
``````

## Transforming with Map

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

``````const nums = [1, 2, 3, 4, 5];
const map= nums.map(x => x*2);

console.log(map);
-> [2, 4, 6, 8, 10]
``````

In the above program, we are taking individual value and multiplying it with 2 to make it double and returning in the form of a new array.

map and filter work the same in their initial stage i.e. taking every element into account and perform some action on it. Also, both create a new array. But the difference comes on the return stage.
map returns the whole array while filter returns the filtered values in the form of an array.

## Summarizing with Reduce

reduce() method can be used to take a whole array and evaluates a single value out of it based on some function. It takes three parameters.

1. array
2. combining function
3. starting value

Starting value is optional if you want to perform the function on the whole array.

``````const array = [1, 2, 3, 4];
const reduce = array.reduce((a, b) => a+b);

console.log(reduce);
-> 10
``````

As you can guess it is summing up the array elements. But, the function is a little bit confusing to you.. At least I think so. So, let me explain what it is doing.

if we put `console.log` before `a+b`

``````const array = [1, 2, 3, 4];
const reduce = array.reduce((a, b) => {
console.log(a, b);
return a+b;
});

console.log(reduce);
``````

Since we are putting more than one line of code we need to put the curly braces and also put the `return` keyword.
Back to the topic, if you put that line you will see something like

``````1 2
3 3
6 4

10             //result
``````

Now, you understood a little bit or maybe fully. But let me explain. It is first taking the first two elements of the array and summing it up.
Then in the further iterations, it is taking the `sum` of the previous two elements and the next element in the array.

And this will go on till the end of the array.

Thanks for reading!😊