【问题标题】:Flatten a Map of Option to Map [duplicate]将选项图展平到地图 [重复]
【发布时间】:2015-12-11 22:23:53
【问题描述】:

我有一个Map[A, Option[B]],制作扁平化以获得Map[A, B] 的最佳方法是什么?

我知道我们可以使用 flatten 的列表,但这种结构不同

【问题讨论】:

    标签: scala


    【解决方案1】:

    好吧,它们并不相同,因此您需要一种方法来定义如果值为 None 会发生什么。我假设您想忽略这些键,如果是这样,您可以使用部分函数进行收集:

    map.collect {
      case (k, Some(v)) => k -> v
    }
    

    或使用理解

      for ((k, Some(v)) <- map) yield k -> v
    

    【讨论】:

    • 是的,我没有准确地说我不想要具有 None 值的键,非常感谢您的回答!
    • 其实for ((k, Some(v)) &lt;- map ) yield k -&gt; v就够了
    • 非常真实!我会更新的!那个模式匹配上面而不是下面吗,白痴......
    【解决方案2】:

    如果你不介意双迭代:

    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 想要的。
    • @jhn 取决于,如果 mapValues 中的代码像我的答案一样是参照透明的,那么为什么有人要关心?对于 Java 序列化(如果出于某种原因仍在使用它),总是有 .view.force 或 .map(identity)
    • 为什么要有人关心?性能。
    • @jhn 首先,“如果你不介意双迭代”的意思是“如果你不太关心性能”。其次,视图实际上提高了大型集合的性能,因为它不会创建中间集合(因此更少的 GC),这就是 mapValues 实际上创建视图的原因。当然,每次使用视图时都会调用get,但是这里的性能损失是有问题的(它仍然是线性的 - 其他任何事情都取决于具体情况)。不仅如此,问题中没有具体的性能要求——“最优”并不意味着“性能高效”。
    • @jhn 并且,正如它所说,如果你真的因为每次get 而真的发现严重的性能泄漏,你总是可以view.force,在大多数情况下我怀疑(因为它没有' t 改变渐近复杂度)。假设 1% 的性能改进牺牲了代码的可读性,这并不是“最佳的”。无论如何,只有性能测试(对于真正的 OP 的情况)可以明确地说你是否应该使用视图
    猜你喜欢
    • 2020-07-06
    • 2014-10-26
    • 2019-04-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-01
    • 2015-04-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多