35

我已经搜索了一下,但还没有找到一个很好的答案,关于如何过滤掉映射中值为 None 的任何条目。假设我有一张这样的地图:

val map = Map[String, Option[Int]]("one" -> Some(1), 
                                   "two" -> Some(2), 
                                   "three" -> None)

我想最终返回一张只有("one", Some(1))and("two", Some(2))对的地图。我知道当你有一个列表时,这是通过 flatten 完成的,但我不确定如何在不将其拆分为键和值,然后尝试重新加入它们的情况下在地图上实现效果。

4

3 回答 3

58

如果您要过滤掉None值,您不妨同时提取这些Some值以得到Map[String,Int]

scala> map.collect { case (key, Some(value)) => (key, value) }
res0: scala.collection.immutable.Map[String,Int] = Map(one -> 1, two -> 2)
于 2012-08-07T23:01:34.527 回答
38

就像 scala.collection 命名空间中的每个集合类型一样,a定义Map了方法并具有方法,即for和for 。您可以通过组合这两个来过滤掉这些值:filterOptionisDefinedtrueSomefalseNoneNone

scala> map.filter(_._2.isDefined)
res4: scala.collection.immutable.Map[String,Option[Int]] = Map(one -> Some(1), two -> Some(2))
于 2012-08-07T21:34:55.070 回答
6

map.filterKeys( map(_) != None)

或者

for( (k,v) <- map if( v!= None)) yield (k,v)

这种方法提供了地图上不存在的通用 filterValues 方法。
我想念这样的方法,因为没有一个选择是完美的。

[稍后更新] 这是一个更好的版本,它不会对每个条目进行查找,并且仍然可以合理清晰地阅读。

map.filter( {case (x,y)=> y!=None})

于 2013-11-19T20:05:56.833 回答