如何将Map 转换为Scala中的SortedMap? 还是一个TreeMap?
我想将Map[Int, Any]
转换为SortedMap
或者TreeMap
。 有一个简单的方法来做到这一点?
假设你正在使用不可变的地图
val m = Map(1 -> "one") val t = scala.collection.immutable.TreeMap(m.toArray:_*)
TreeMap
伴随对象的apply方法使用重复的映射入口参数(这是相应参数types的Tuple2[_, _]
的实例)。 toArray
生成一个Array[Tuple2[Int, String]]
(在这种情况下)。 : _*
告诉编译器数组的内容将被视为重复的参数。
用sblundy描述的另一种方法是将现有的地图追加到一个空的SortedMap
import scala.collection.immutable.SortedMap val m = Map(1 -> ("one":Any)) val sorted = SortedMap[Int, Any]() ++ m
以下是在各种Scala集合之间进行转换的一般方法。
import collection.generic.CanBuildFrom import collection.immutable.TreeMap object test { class TraversableW[A](t: Traversable[A]) { def as[CC[X] <: Traversable[X]](implicit cbf: CanBuildFrom[Nothing, A, CC[A]]): CC[A] = t.map(identity)(collection.breakOut) def to[Result](implicit cbf: CanBuildFrom[Nothing, A, Result]): Result = t.map(identity)(collection.breakOut) } implicit def ToTraverseableW[A](t: Traversable[A]): TraversableW[A] = new TraversableW[A](t) List(1, 2, 3).as[Vector] List(1, 2, 3).to[Vector[Int]] List((1, 1), (2, 4), (3, 4)).to[Map[Int, Int]] List((1, 1), (2, 4), (3, 4)).to[TreeMap[Int, Int]] val tm: TreeMap[Int, Int] = List((1, 1), (2, 4), (3, 4)).to ("foo": Seq[Char]).as[Vector] } test
另请参阅此问题描述collection.breakOut
: Scala 2.8 breakOut
挑战
是否有可能调整implicits这样的作品? 或者只有as
被添加到Traversable
时才可能这样as
?
"foo".as[Vector]
下面是一个可以用Scala隐式类来实现的方法:
implicit class ToSortedMap[A,B](tuples: TraversableOnce[(A, B)]) (implicit ordering: Ordering[A]) { def toSortedMap = SortedMap(tuples.toSeq: _*) }
由于Map [A,B]具有到TraversableOnce [Tuple2 [A,B]]的隐式path,因此以下工作:
scala> Map("b" -> 3, "c" -> 3, "a" -> 5).toSortedMap res6: scala.collection.immutable.SortedMap[String,Int] = Map(a -> 5, b -> 3, c -> 3)
它甚至可以在Tuple2的列表上工作,类似于Map:
scala> List(("c", 1), ("b", 3),("a", 6)).toSortedMap res7: scala.collection.immutable.SortedMap[String,Int] = Map(a -> 6, b -> 3, c -> 1)
由于实现中的内部数据结构完全不同,因此无论如何您都必须逐个添加元素。 所以,明确地做到这一点:
val m = Map(1 -> "one") var t = scala.collection.immutable.TreeMap[Int,String]() t ++= m