如何过滤从List [(String,Option [Int])]中删除无类型?

时间:2016-11-10 21:39:13

标签: scala

我尝试从None列表中删除(String , Option[Int])类型,其中None类型可以位于元组中的第2位:

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);

但是这不能编译:

导致错误:

 ')' expected but '<-' found.
[error]                 (e <- l)
[error]                    ^

可以flatten使用此集合而不是每个集合吗?

4 个答案:

答案 0 :(得分:5)

与cheseaux的答案类似,但更为惯用:

l.filter(_._2.isDefined)

答案 1 :(得分:2)

为什么不简单

l.filter(_._2 != None)

或者,如果你真的想用for comprehensions表单来表达它,你可以这样做

for(e <- l; if (e._2 != None)) yield e

答案 2 :(得分:2)

你可以通过使用带有一些模式匹配的过滤器来完成同样的事情:

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 
}

以下是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)))

答案 3 :(得分:0)

另一种选择是使用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)))