Scala:从地图中删除任何元素并展平
Posted
技术标签:
【中文标题】Scala:从地图中删除任何元素并展平【英文标题】:Scala: Remove none elements from map and flatten 【发布时间】:2013-06-15 16:21:39 【问题描述】:我有一张地图:
Map("key1" -> Some("value1"), "key2" -> None, "key3" -> Some("value3"))
我想删除所有None
元素并展平地图。实现这一目标的最简单方法是什么?我只发现了这种方式:
Map("key1" -> Some("value1"), "key2" -> None, "key3" -> Some("value3")).filter(_._2.nonEmpty).map(item => (item._1 -> item._2.getOrElse(Nil)))
结果是:
Map(key1 -> value1, key3 -> value3)
你知道更好的方法吗?
【问题讨论】:
为什么不filter
+ mapValues
?
【参考方案1】:
您也可以定义以下帮助程序,以实现更紧凑的语法
implicit class RichPairedOptionIterableOps[A, B, Repr[_]](
iterable: IterableOps[(A, Option[B]), Repr, Repr[(A, Option[B])]]
)
def collectWithSome: Repr[(A, B)] = iterable.collect case (a, Some(b)) => a -> b
def collectWithNone: Repr[A] = iterable.collect case (a, None) => a
关于你的例子:
Map("key1" -> Some("value1"), "key2" -> None, "key3" -> Some("value3")).collectWithSome
【讨论】:
【参考方案2】:在地图上使用分区,像这样,
val (flattened,_) = map.partition(_._2.isDefined)
【讨论】:
【参考方案3】:你可以使用理解+模式匹配:
for((k, Some(v)) <- yourMap) yield k -> v
【讨论】:
现在这很优雅。我从来没有想过这个:) @felix 我完全同意【参考方案4】:我的理解是:
val m = Map("key1" -> Some("value1"), "key2" -> None, "key3" -> Some("value3"))
for( (key,value) <- m if(value.isDefined)) yield (key,value.get)
【讨论】:
顺便也可以写成for((key, maybeVal) <- m; value <- maybeVal) yield key -> value
@om-nom-nom 甚至for ((k, Some(v)) <- map ) yield k -> v
+1,因为它还将地图类型从 Map[String, Option[String]]
更改为 Map[String, String]
,本质上不仅扁平化了值,而且扁平化了类型。【参考方案5】:
我对模式匹配的看法是:
Map("key1" -> Some("value1"), "key2" -> None, "key3" -> Some("value3")).collect
case (key, Some(value)) => key -> value
// Map(key1 -> value1, key3 -> value3)
Collect 就像组合地图 + 过滤器
【讨论】:
以上是关于Scala:从地图中删除任何元素并展平的主要内容,如果未能解决你的问题,请参考以下文章