In Scala, a higher-order function is a function which takes another function as an argument. A higher-order function describes "how" the work is to be done in a collection.
Let's learn the higher order function map. The map applies the function to each value in the collection and returns a new collection. Say we have a list of integers 3, 7, 13 and 16 and we want to add one to each value in the list. Using higher order map function, we can map over the list and add one to each value. As displayed on the screen, we have a new list with values 4, 8, 14 and 17.
Let's do a hands-on. Define a list of integers 1, 2 and 3. Type,
var list = List(1,2,3)
Let's add 1 to each element using the map function. To define a map function, type list.map(x => x + 1). Press enter. As you can see, we have a new list with integers 2, 3 and 4
Here map function adds one to every value in the list. Each value in the list has the name "x". There is another syntax to define the map, where instead of giving a name to every value being used in the function, we use a placeholder underscore to represent the value.
Let's learn the higher order function flatMap.
Flatmap takes a function as an argument and this function must return a collection. The collection could empty.
The flatMap is called on a collection. The flatmap applies the function passed to it as an argument on each value in the collection just like map.
The returned collections from each call of function are then merged together to form a new collection.
Let's understand it with an example
Let's define a list of languages. Type,
var list = List("Python", "Go")
Here, we have a list of strings. A string is nothing but a sequence of characters. Define a flatMap.
Type list.flatMap(lang => lang + "#"). flatMap appends "#" to every string in the list and then flattens down the string to characters. As you can see on the screen, # is appended to python and go and then "python#" and "go#" flatten down into the sequence of characters. We can also define the same function using the following flatMap(_+ "#") where the underscore is a placeholder for each value in the list.
So, the size of output collection could be larger than the size of input collection.
While in case of map the input and output collection were of the same size.
Let's learn the higher order function Filter. The filter applies a function to each value in the collection and returns a new collection with values that satisfy a condition specified in the function. Let's understand it with an example.
We have a list of languages Scala, R, Python, Go and SQL. To filter out languages which contain capital S, type
list.filter(lang => lang.contains("S"))
As you can see we have a new list now with only Scala and SQL as values. Each value in the list has name "lang"
Each of the previous higher order functions returned a new collection after applying the transformation. But at times we do not want the functions to return a new collection. It is a waste of memory resources on JVM if we do not want a return value. Higher order function 'foreach' allows us to apply a function to each value of collection without returning a new collection. Let's say we have a list of values 1 and 2 and we just want to print each value in the list. We can use foreach function for this as we are not interested in the return value. To use foreach higher order function, type
As you can see value 1 and 2 are printed on the screen.
Let's learn higher order function 'reduce'. Reduce is a very important concept in the MapReduce world. Let's say we have a list and we want to reduce it to add values together. Let's understand it with an example. We've a list of integers 3, 7, 13 and 16.
In our example, reduce adds the first two elements 3 and 7 which results in 10. Then it adds 10 to the next element which is 13 resulting in 23. Then it adds 23 to the next element in the list which is 16. As you can see, that final result of the reduce function is 39
Let's do a hands-on. We have a list of integers 3, 7, 13, 16. Let's define a reduce function to add the elements, type
list.reduce((x, y) => x + y)
As we can see, the result is 39. Here the reduce function takes two values named x and y and adds them.
We can also define the reduce function using list.reduce(_ + _). Here the two underscores are placeholders for the two values.