Reputation: 53806
Here I'm attempting to remove None
type from a list of (String , Option[Int])
where the None
type can be at position 2 in the tuple :
val l : List[(String , Option[Int])] = List(
("a" , None),
("b" , Option(1)),
("c" , Option(2))
)
val filteredSomes = for {
(e <- l)
if(e._2 >= 0)
} yield e
println(filteredSomes);
But this does not compile :
causes error :
')' expected but '<-' found.
[error] (e <- l)
[error] ^
Can flatten
be used against this collection instead of for each ?
Upvotes: 2
Views: 4484
Reputation: 422
Another option is to use collect
List(
("a" , None),
("b" , Option(1)),
("c" , Option(2)),
("d", Option(-1))
) collect {case t @ (_, Some(i)) if i >= 0 => t}
//result: List((b,Some(1)), (c,Some(2)))
Upvotes: 1
Reputation: 18177
You can accomplish the same thing by using a filter with some pattern matching:
val filteredSomes = l.filter {
// This is the only case that you want to pass your filter.
// We are pattern matching the tuple and saying that we don't
// care about the String's value but we want the Option[Int]
// to be defined and be greater-than-or-equal to zero
case (_, Some(i)) if i >= 0 => true
// Any other case should not pass the filter
case _ => false
}
Here is an example from the Scala REPL
scala> val l : List[(String , Option[Int])] = List(("a" , None), ("b" , Option(1)), ("c" , Option(2)))
l: List[(String, Option[Int])] = List((a,None), (b,Some(1)), (c,Some(2)))
scala> l.filter {
| case (_, Some(i)) if i >= 0 => true
| case _ => false
| }
res6: List[(String, Option[Int])] = List((b,Some(1)), (c,Some(2)))
Upvotes: 2
Reputation: 247
Similar to the cheseaux's answer, but more idiomatic:
l.filter(_._2.isDefined)
Upvotes: 9
Reputation: 5315
Why not simply
l.filter(_._2 != None)
Or if you really want to express it using the for comprehensions
form, you can do it like this
for(e <- l; if (e._2 != None)) yield e
Upvotes: 2