【问题标题】:Scala: Implicit evidence of Map with Traversable values?Scala:具有可遍历值的 Map 的隐式证据?
【发布时间】:2015-03-18 06:52:09
【问题描述】:

我正在尝试编写一个通用的 invert 方法,该方法将 Map 从 A 类型的键获取到 B 类型的集合的值,并将其转换为具有 B 类型的键的 Map 和A 的集合使用相同的原始集合类型。

我的目标是让这个方法成为MyMap[A,B] 类的成员,该类提供基本库方法的扩展,其中Maps 隐式转换为MyMaps。我能够为通用映射执行此隐式转换,但我想进一步指定 invert 方法应该只在 B 是一个集合的情况下工作。

我缺乏对 scala 集合框架的理解来实现这一点 - 我已经在网上搜索了对看起来像 ReprCCThatCanBuildFrom 大杂烩的签名的彻底介绍性解释,但我真的不明白所有这些部分是如何很好地结合在一起来构建我自己的方法签名的。请不要只给我这个案例的工作签名 - 我想了解使用泛型集合的方法的签名在更广泛的意义上是如何工作的,这样我就能够独立地继续前进。或者,请随意参考详细说明此问题的在线资源 - 我找不到全面而清晰的资源。

编辑

我似乎已经让它与以下代码一起工作。如果我做错了什么,或者您发现有什么可以改进的地方,请发表评论并用更优化的替代方案进行回答。

class MyMap[A, B](val _map: Map[A, B]) {
  def invert[E, CC[E]](
    implicit ev1: B =:= CC[E],
    ev2: CC[E] <:< TraversableOnce[E],
    cbf: CanBuildFrom[CC[A], A, CC[A]]
  ): Map[E, CC[A]] = {
    val inverted = scala.collection.mutable.Map.empty[E, Builder[A, CC[A]]]
    for {
      (key, values) <- _map
      value <- values.asInstanceOf[CC[E]]
    } {
      if (!inverted.contains(value)) {
        inverted += (value -> cbf())
      }
      inverted.get(value).foreach(_ += key)
    }
    return inverted.map({ case (k,v) => (k -> v.result) }).toMap
  }
}

【问题讨论】:

    标签: scala collections


    【解决方案1】:

    我从你的代码开始,最终得到了这个:

    implicit class MyMap[A, B, C[B] <: Traversable[B]](val _map: Map[A, C[B]]) {
    
      def invert(implicit cbf: CanBuildFrom[C[A], A, C[A]]): Map[B, C[A]] = {
        val inverted = scala.collection.mutable.Map.empty[B, Builder[A, C[A]]]
        for ((k, vs) <- _map; v <- vs) {
          inverted.getOrElseUpdate(v, cbf()) += k
        }
    
        inverted.map({ case (k, v) => (k -> v.result)}).toMap
      }
    }
    
    val map = Map("a"-> List(1,2,3), "b" -> List(1,2))
    
    println(map.invert) //Map(2 -> List(a, b), 1 -> List(a, b), 3 -> List(a))
    

    【讨论】:

    • 我希望该类足够通用以处理任何类型的地图,因此我可以为地图添加其他扩展。我只希望特定的invert 方法具有B 是一个集合的附加要求。
    猜你喜欢
    • 1970-01-01
    • 2015-05-23
    • 1970-01-01
    • 2019-07-20
    • 1970-01-01
    • 2017-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多