Reputation: 443
val c = s.split(" ").filter(_.startsWith("#")).filter(x =>
x.contains("worcester") || x.contains("energy"))
Works
But this does not
val c = s.split(" ").filter(_.startsWith("#")).filter(_.contains("worcester") ||
_.contains("energy"))
I have not understood it clearly why the latter does not work - may be I have a flaw in my fundamentals
Any help would be very appreciated thanks Sumit
Upvotes: 1
Views: 301
Reputation: 16324
Using underscore like this is known as placeholder syntax. So, something like _.contains("x")
is equivalent to x => x.contains("x")
. You can only use each parameter once when using the placeholder syntax. Using multiple placeholders denotes multiple parameters of the anonymous function (which are then used in order of the underscores). So, when you write:
o.filter(_.contains("worcester") || _.contains("energy"))
It would theoretically be equivalent to
o.filter((x, y) => x.contains("worcester") || y.contains("energy"))
Which doesn't type check, since filter
expects a parameter of type Array[String] => Boolean
.
Multiple placeholders are common when using the reduce
variants. For example, a factorial can be computed as (1 to n).reduce(_ * _)
. This works because reduce
expects a parameter of type (Int, Int) => Int
, so _ * _
, which is equivalent to (x, y) => x * y
fits the expected type.
It's important to note that the placeholder syntax applies to the smallest possible scope. So, for example, f(g(_))
is equivalent to f(x => g(x))
, and not x => f(g(x))
, which is a common mistake.
You can find a comprehensive list of the use of underscore in Scala here, and a little bit more about the placeholder syntax here.
Upvotes: 5