【发布时间】:2015-12-11 22:23:53
【问题描述】:
我有一个Map[A, Option[B]],制作扁平化以获得Map[A, B] 的最佳方法是什么?
我知道我们可以使用 flatten 的列表,但这种结构不同
【问题讨论】:
标签: scala
我有一个Map[A, Option[B]],制作扁平化以获得Map[A, B] 的最佳方法是什么?
我知道我们可以使用 flatten 的列表,但这种结构不同
【问题讨论】:
标签: scala
好吧,它们并不相同,因此您需要一种方法来定义如果值为 None 会发生什么。我假设您想忽略这些键,如果是这样,您可以使用部分函数进行收集:
map.collect {
case (k, Some(v)) => k -> v
}
或使用理解
for ((k, Some(v)) <- map) yield k -> v
【讨论】:
for ((k, Some(v)) <- map ) yield k -> v就够了
如果你不介意双迭代:
map.filter(_._2.nonEmpty).mapValues(_.get)
例子:
scala> Map(1 -> Some(1), 2 -> None).filter(_._2.nonEmpty).mapValues(_.get)
res9: scala.collection.immutable.Map[Int,Int] = Map(1 -> 1)
或者使用这个隐式:
implicit def flat[K,V](kv: (K, Option[V])) = kv._2.map(kv._1 -> _).toList
然后:
map.flatten.toMap
或者不使用(可能不安全的)隐式:
map flatMap flat
例子:
scala> Map(1 -> Some(1), 2 -> None).flatten.toMap
res2: scala.collection.immutable.Map[Int,Int] = Map(1 -> 1)
scala> def flat[K,V](kv: (K, Option[V])) = kv._2.map(kv._1 -> _).toList
warning: there was one feature warning; re-run with -feature for details
flat: [K, V](kv: (K, Option[V]))List[(K, V)]
scala> Map(1 -> Option(1), 2 -> None).flatMap(flat)
res29: scala.collection.immutable.Map[Int,Int] = Map(1 -> 1)
【讨论】:
mapValues 返回地图上的视图,这可能不是 OP 想要的。
mapValues 实际上创建视图的原因。当然,每次使用视图时都会调用get,但是这里的性能损失是有问题的(它仍然是线性的 - 其他任何事情都取决于具体情况)。不仅如此,问题中没有具体的性能要求——“最优”并不意味着“性能高效”。
get 而真的发现严重的性能泄漏,你总是可以view.force,在大多数情况下我怀疑(因为它没有' t 改变渐近复杂度)。假设 1% 的性能改进牺牲了代码的可读性,这并不是“最佳的”。无论如何,只有性能测试(对于真正的 OP 的情况)可以明确地说你是否应该使用视图