I'm new in scala. Is there any the differences between the high order function follow brace or parentheses block?
For example:
List(1, 2, 3).map(i=> i + 1)
List(1, 2, 3).map {i => i + 1}
Both of them get same result: List(2, 3, 4)
But for this example List(1, 2).map { println("Hi"); _ + 1 }
The result is below and why 'Hi' just print once?
Hi
List[Int] = List(2, 3)
One such widely used method offered by Scala is map (). map () is a higher order function. Every collection object has the map () method. map () takes some function as a parameter. map () applies the function to every element of the source collection. map () returns a new collection of the same type as the source collection.
Important points about map () method: 1 map () is a higher order function. 2 Every collection object has the map () method. 3 map () takes some function as a parameter. 4 map () applies the function to every element of the source collection. 5 map () returns a new collection of the same type as the source collection.
The returned DataFrame can have the same count or more elements than the current DataFrame. This is one of the major differences between flatMap () and map (), where map () transformation always returns the same number of elements as in input. flatMap [ U]( f : scala. Function1 [ T, scala.
You can iterate through the keys and values of a Map using “foreach” loop. Here, we used method foreach associated with iterator to walk through the keys. Following is the example program. Save the above program in Demo.scala. The following commands are used to compile and execute this program.
A block in Scala is just an expression. Like parentheses, they are useful for grouping code together. Unlike parentheses, blocks don't contain just one expression, but can contain 1 or more expressions. The value of a block is the value of the last expression in it.
{ println("Hi"); _ + 1 }
is equivalent to { println("Hi"); (i: Int) => i + 1 }
. This is a block that prints out "Hi"
, and it's value is a function that adds one. The string is printed before execution exits the block, and the function that it produces doesn't know anything about the println
.
Here are some examples of these rules:
list.map(i => i + 1)
// ^----------^
// function literal passed as argument
list.map(_ + 1)
// ^---^
// Underscore shorthand for above
list.map({ i => i + 1 })
// Identical to above.
// The block only contains one expression, so it has the value of that expression
// Otherwise stated: { expr } === expr
list.map({ println("Hi"); _ + 1 })
// ^-----2-----^ ^-3-^
// ^------------1---------^
// 1: The argument to map is the value of this block
// 2: The first statement of the block prints something. This is only executed once,
// because it's not the *block* being passed as argument, it's its value.
// 3: Function literal in underscore notation. This is the value of the block
// and this is what map sees.
// Order of operations (approx. bytecode):
// load list onto stack
// load string "Hi" onto stack
// call println and pop string off stack
// create function (i => i + 1) on top of stack
// invoke map with argument (i => i + 1), popping list and function off stack
list.map { println("Hi"); _ + 1 }
// Identical to above, but Scala lets you omit the () because you are using {}
list.map({ i => println("Hi"); i + 1 })
// Function literals grow as big as they can be.
// The block contains only one expression, which is (i => println("Hi"); i + 1)
// This function prints "Hi" and then returns i + 1
// This call to map will print "Hi" for every element
list.map { i => println("Hi"); i + 1 }
// Identical to above, but Scala lets you omit the () because you are using {}
Additionally, there are by-name parameters to deal with. By-name parameters are declared like so:
def func(a: => String) // Not () => String, it's => String
When you have by-name parameter, then
func { println("x"); _ + 1 }
actually passes the whole block as argument. The block still evaluates to i => i + 1
, but func
is in control of when that evaluation happens. Specifically, the code of the block is turned into a Function0
and passed into func
, which can call it as many times as it likes, with side effects. This can be used to great effect, essentially allowing normal functions to act like custom control flow operators:
@tailrec def repeat(i: Int)(op: => Any): Unit
= if(i == 0) ()
else {
require(i >= 0, s"negative repeat amount: $i")
op // Evaluate op
repeat(i - 1)(op) // Won't evaluate op; will let sub-call deal with it
}
repeat(5) { println("Hi"); println("Bye") }
// Hi
// Bye
// Hi
// Bye
// Hi
// Bye
// Hi
// Bye
// Hi
// Bye
Note how the parentheses are omitted around the block, which really makes this seem like the ability to define a control flow operator.
In general, you would use parentheses for enclosing simple function parameters:
l.map( x => x * 2 )
and curly braces for enclosing more complex code block or partial functions including case
pattern matching:
l.map{ x =>
val y = x * 2
y
}
l.map{
case x if x%2 == 0 => x * 2
case _ => 0
}
As to the reason why Hi
is only printed once, List(1, 2).map{ println("Hi"); _ + 1 }
is no different from List(1, 2).map{ println("Hi"); x => x + 1 }
. To include println
in the map
iteration:
List(1, 2).map{ x => println("Hi"); x + 1 }
// Hi
// Hi
// res1: List[Int] = List(2, 3)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With