gpt4 book ai didi

scala - Map到TreeMap的深度转换

转载 作者:行者123 更新时间:2023-12-01 00:56:41 24 4
gpt4 key购买 nike

我需要将任意嵌套的 Map 转换为 TreeMap。例子:

Map[Int, String] -> TreeMap[Int, String]
Map[Int, Map[Int, String]] -> TreeMap[Int, TreeMap[Int, String]]
... etc

我有类型体操和隐式转换的工作解决方案,但是我有类型问题
trait ToTreeMap[M[_, _], K, V] {
type Result

def treeMap(x: M[K, V]): TreeMap[K, Result]
}

trait LowerPriorityToTreeMap {
implicit def plainMap[K, V](implicit ord: Ordering[K]): ToTreeMap[Map, K, V] =
new ToTreeMap[Map, K, V] {
type Result = V

def treeMap(x: Map[K, V]): TreeMap[K, Result] = TreeMap(x.toArray: _*)
}
}

object ToTreeMap extends LowerPriorityToTreeMap {
implicit def nestedMap[K1, K2, V](implicit inner: ToTreeMap[Map, K2, V], ord: Ordering[K1]): ToTreeMap[Map, K1, Map[K2, V]] = {
new ToTreeMap[Map, K1, Map[K2, V]] {
type Result = TreeMap[K2, inner.Result]

def treeMap(x: Map[K1, Map[K2, V]]): TreeMap[K1, Result] = TreeMap(x.mapValues(v => inner.treeMap(v)).toArray: _*)
}
}

implicit class MapOps[K, V](map: Map[K, V]) {
def asTreeMap(implicit as: ToTreeMap[Map, K, V]) = as.treeMap(map)
}
}

这工作正常,但是类型 ToTreeMap[..]#Result 与我需要的 TreeMap 不匹配
  import ToTreeMap._

val map: Map[Int, Map[Int, Map[Int, String]]] =
Map(
1000 -> Map(
100 -> Map(
10 -> "aa",
1 -> "bb"
),
99 -> Map(
10 -> "aa",
1 -> "bb"
)
),
999 -> Map(
100 -> Map(
10 -> "aa",
1 -> "bb"
),
99 -> Map(
10 -> "aa",
1 -> "bb"
)
)
)

val m = Map(1 -> "aaa")

println(map.asTreeMap)
println(m.asTreeMap)

// This line fails to compile
val tm: TreeMap[Int, TreeMap[Int, TreeMap[Int, String]]] = map.asTreeMap

任何想法如何正确地做到这一点?

Scalac 在这个例子中选择了正确的类型: Two dimensional array as a function这和我想的没有太大区别

我可以用 'asIntanceOf' 解决这种类型的问题,但我想在没有这个肮脏的黑客的情况下做到这一点。

最佳答案

您需要确保不要扔掉Return实例方法的返回类型中的值:

trait ToTreeMap[M[_, _], K, V] {
type Result

def treeMap(x: M[K, V]): TreeMap[K, Result]
}

trait LowerPriorityToTreeMap {
implicit def plainMap[K, V](
implicit ord: Ordering[K]
): ToTreeMap[Map, K, V] { type Result = V } =
new ToTreeMap[Map, K, V] {
type Result = V

def treeMap(x: Map[K, V]): TreeMap[K, Result] = TreeMap(x.toArray: _*)
}
}

object ToTreeMap extends LowerPriorityToTreeMap {
implicit def nestedMap[K1, K2, V](
implicit inner: ToTreeMap[Map, K2, V], ord: Ordering[K1]
): ToTreeMap[Map, K1, Map[K2, V]] {
type Result = TreeMap[K2, inner.Result]
} = {
new ToTreeMap[Map, K1, Map[K2, V]] {
type Result = TreeMap[K2, inner.Result]

def treeMap(x: Map[K1, Map[K2, V]]): TreeMap[K1, Result] =
TreeMap(x.mapValues(v => inner.treeMap(v)).toArray: _*)
}
}

implicit class MapOps[K, V](map: Map[K, V]) {
def asTreeMap(implicit as: ToTreeMap[Map, K, V]) = as.treeMap(map)
}
}

这有效,对我来说看起来非常合理。

关于scala - Map到TreeMap的深度转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27305888/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com