Как мне преобразовать карту [Int, Any] в SortedMap в Scala?Или TreeMap? - PullRequest
37 голосов
/ 19 июня 2010

Я хотел бы преобразовать Map[Int, Any] в SortedMap или TreeMap.Есть ли простой способ сделать это?

Ответы [ 6 ]

43 голосов
/ 19 июня 2010

Альтернативой использованию :_*, как описано sblundy, является добавление существующей карты к пустой SortedMap

import scala.collection.immutable.SortedMap
val m = Map(1 -> ("one":Any))
val sorted = SortedMap[Int, Any]() ++ m
43 голосов
/ 19 июня 2010

Предполагается, что вы используете неизменяемые карты

val m = Map(1 -> "one")
val t = scala.collection.immutable.TreeMap(m.toArray:_*)

Метод применения объекта-компаньона TreeMap принимает повторные параметры ввода карты (которые являются Tuple2[_, _] соответствующих типов параметров).toArray производит Array[Tuple2[Int, String]] (в данном конкретном случае).: _* сообщает компилятору, что содержимое массива следует рассматривать как повторяющиеся параметры.

33 голосов
/ 19 июня 2010

Вот общий способ конвертации различных коллекций 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

ВЫЗОВ

Можно ли настроить последствия так, чтобы это работало? Или это было бы возможно только если as были добавлены к Traversable?

"foo".as[Vector]
4 голосов
/ 08 февраля 2014

Вот способ, которым вы можете сделать это с неявным классом 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]], следующееработает:

scala> Map("b" -> 3, "c" -> 3, "a" -> 5).toSortedMap
res6: scala.collection.immutable.SortedMap[String,Int] = Map(a -> 5, b -> 3, c -> 3)

Он будет работать даже в списке Tuple2s, аналогично toMap:

scala> List(("c", 1), ("b", 3),("a", 6)).toSortedMap
res7: scala.collection.immutable.SortedMap[String,Int] = Map(a -> 6, b -> 3, c -> 1)
2 голосов
/ 11 октября 2010

Поскольку внутренние структуры данных в реализациях совершенно разные, вам все равно придется добавлять элементы один за другим.Итак, сделайте это явно:

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

var t = scala.collection.immutable.TreeMap[Int,String]()
t ++= m
0 голосов
/ 30 июня 2019

Начиная с Scala 2.13, через заводских строителей, применяемых с .to(factory):

Map(1 -> "a", 2 -> "b").to(collection.immutable.SortedMap)
// collection.immutable.SortedMap[Int,String] = TreeMap(1 -> "a", 2 -> "b")
Map(1 -> "a", 2 -> "b").to(collection.immutable.TreeMap)
// collection.immutable.TreeMap[Int,String] = TreeMap(1 -> "a", 2 -> "b")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...