Scala 如何筛选并从列表[(字符串,选项[Int])]中删除无类型?

Scala 如何筛选并从列表[(字符串,选项[Int])]中删除无类型?,scala,Scala,这里我试图从(字符串,选项[Int])列表中删除None类型,其中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)

这里我试图从
(字符串,选项[Int])
列表中删除
None
类型,其中
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);
val l:List[(字符串,选项[Int])]=List(
(“a”,无),
(“b”,选项(1)),
(“c”,备选案文(2))
)
val filteredSomes=用于{
(e=0)
}产量e
println(filteredSomes);
但这并没有编译:

导致错误的原因:

 ')' expected but '<-' found.
[error]                 (e <- l)
[error]                    ^
”)“应该是,但为什么不简单呢?”

l.filter(_._2 != None)
或者,如果您确实想使用
for comprehensions
表单来表达它,您可以这样做

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

(e类似于cheseaux的答案,但更惯用:

l.filter(_._2.isDefined)

通过使用具有某种模式匹配的过滤器,您可以完成相同的任务:

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

另一个选项是使用
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)))

但是,
选项
上的模式匹配通常是一种代码气味。有太多有用的
选项
组合符,几乎不需要模式匹配。例如,请更简洁地参见:
以获取(a@(uu,某些(b))0)产生一个
@Jubobs我想说这是一个在
选项
上进行模式匹配的例子,因为它使
I
的来源更加清晰。另一方面,当映射到一个文本
时,通常有更好的方法。@MichaelZajac我个人更喜欢
>l filter{{uu.\u2 exists{{uu>=0}
@Jubobs我不知道选项上的模式匹配是一种糟糕的做法,感谢视频!非负约束在哪里?如果我正确理解OP想要什么,表达式应该是
l.filter({uu.\u2.exists({u>=0))
.Oh,我没有看到那部分。你也可以折叠选项:1.过滤(.\u 2.折叠(false)(>=0)),这是basicall的意思,如果.\u 2是None,那么返回false,否则返回结果>=0如果你想去掉选项monad,你也可以将tuple
case(s,Some(I))=>s->I