Reputation: 15284
I am trying to use placeholder syntax for simple map:
Array(1,2,3).map(if(_ % 2 == 0) _ * 2)
I was expecting to have the same effect as:
Array(1,2,3).map(i=>if (i%2==0) i * 2)
It complains
error: type mismatch;
found : Unit
required: Int => ?
I also tried:
Array(1,2,3).map(if(_ % 2 == 0) _ * 2 else _) //with else
Array(1,2,3).map(if((_:Int) % 2 == 0) (_:Int) * 2 else (_:Int)) //All typed
Array(1,2,3).map(if((_:Int) % 2 == 0) 0 else 1) //Typed and specific return Int
Every one of them gives error. How to properly use this syntax in this case?
Edit
The link states that filter(_:Boolean)
and filter (_ == true)
should work, but my trials with specific typing does not work. This link also states that if (_) x else y
should work, but in my case it does not. Need more explanation.
Edit 2
Tried:
Array(true,false).map(if(_) 0 else 1)
It works. But my case:
Array(1,2,3).map(if((_) % 2 == 0) 0 else 1)
Does not work.
Does this syntax only support such simple expressions?
Upvotes: 1
Views: 518
Reputation: 22439
Re: your original question:
Array(1, 2, 3).map(if (_ % 2 == 0) _ * 2)
// error: missing parameter type for expanded function ...
// error: type mismatch ...
The _
placeholder used in such pattern represents positional parameters of an anonymous function, hence if (_ % 2 == 0) _ * 2
is equivalent to:
if (x => x % 2 == 0) y => y * 2
That explains the missing parameter
error. The type mismatch
error is due to missing else
in the if
statement, forcing the compiler to return a Unit
:
Array(1, 2, 3).map(i => if (i % 2 == 0) i * 2 else i)
// res1: Array[Int] = Array(1, 4, 3
Given that you need to specify the single input multiple times I'm not sure it'll work for you.
As you've already noticed, this placeholder syntax does have its limitation and should be treated as a convenient shortform for relatively simple cases. Like the if (_ % 2 == 0) 0 else 1)
case, nesting _
within a map
generally does not work well. For example:
List("a", "b", "c").map(_ * 3)
// res2: List[String] = List(aaa, bbb, ccc)
List("a", "b", "c").map((_ + " ") * 3)
// error: missing parameter type for expanded function ...
For more usage re: _
, here is a SO link, and a Scala doc about commonly used symbols including _
.
Upvotes: 3