【发布时间】:2015-03-18 06:52:09
【问题描述】:
我正在尝试编写一个通用的 invert 方法,该方法将 Map 从 A 类型的键获取到 B 类型的集合的值,并将其转换为具有 B 类型的键的 Map 和A 的集合使用相同的原始集合类型。
我的目标是让这个方法成为MyMap[A,B] 类的成员,该类提供基本库方法的扩展,其中Maps 隐式转换为MyMaps。我能够为通用映射执行此隐式转换,但我想进一步指定 invert 方法应该只在 B 是一个集合的情况下工作。
我缺乏对 scala 集合框架的理解来实现这一点 - 我已经在网上搜索了对看起来像 Repr、CC、That 和 CanBuildFrom 大杂烩的签名的彻底介绍性解释,但我真的不明白所有这些部分是如何很好地结合在一起来构建我自己的方法签名的。请不要只给我这个案例的工作签名 - 我想了解使用泛型集合的方法的签名在更广泛的意义上是如何工作的,这样我就能够独立地继续前进。或者,请随意参考详细说明此问题的在线资源 - 我找不到全面而清晰的资源。
编辑
我似乎已经让它与以下代码一起工作。如果我做错了什么,或者您发现有什么可以改进的地方,请发表评论并用更优化的替代方案进行回答。
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