2016-11-10 18 views
1

在这里,我试图从(String , Option[Int])列表中移除None类型,其中None类型可以是在元组位置2:如何从列表[(String,Option [Int])]中删除无类型?

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而不是每个?

回答

5

类似于瑞士Cheseaux的答案,但更地道:

l.filter(_._2.isDefined) 
+2

哪里非负约束?如果我正确理解OP要的是什么,表达式应该是'l.filter(_._ 2.exists(_> = 0))'。 – Jubobs

+0

哦,我没有看到那部分。您也可以折叠选项: 1.filter(_._ 2.fold(false)(_> = 0)) 哪一个basicall表示如果_._ 2是None,则返回false,否则返回结果> = 0 – rleibman

2

为什么不干脆

l.filter(_._2 != None) 

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

for(e <- l; if (e._2 != None)) yield e 
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 
} 

这里是斯卡拉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))) 
+1

尽管在Option中模式匹配通常是一种代码味道。有很多有用的'Option'组合器,几乎不需要模式匹配。例如,请参阅https://www.youtube.com/watch?v=ol2AB5UN1IA – Jubobs

+0

更简洁地说:'for(a @(_,Some(b))<- l if b > 0)yield a' –

+0

@Jubobs我会说这个有一种情况是在Option中进行模式匹配可能更受欢迎,因为它可以让我们更清楚地知道'i'的来源。另一方面,当映射到文字'true'或'false'时,通常有更好的方法。 –

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))) 
相关问题