如何在 Scala 中将 Map[Int, Any] 转换为 SortedMap?还是树图?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3074118/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 02:14:23  来源:igfitidea点击:

How do I convert a Map[Int, Any] to a SortedMap in Scala? Or a TreeMap?

scala

提问by Vonn

I would like to convert a Map[Int, Any]to a SortedMapor a TreeMap. Is there an easy way to do it?

我想将 a 转换Map[Int, Any]为 aSortedMap或 a TreeMap。有没有简单的方法来做到这一点?

回答by Ben Lings

An alternative to using :_*as described by sblundy is to append the existing map to an empty SortedMap

:_*sblundy 所描述的使用的替代方法是将现有地图附加到一个空的SortedMap

import scala.collection.immutable.SortedMap
val m = Map(1 -> ("one":Any))
val sorted = SortedMap[Int, Any]() ++ m

回答by sblundy

Assuming you're using immutable maps

假设您使用的是不可变映射

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

The TreeMapcompanion object's apply method takes repeated map entry parameters (which are instances of Tuple2[_, _]of the appropriate parameter types). toArrayproduces an Array[Tuple2[Int, String]](in this particular case). The : _*tells the compiler that the array's contents are to be treated as repeated parameters.

TreeMap同伴对象的应用方法需要重复的映射条目的参数(其实例Tuple2[_, _]相应的参数类型)。toArray产生一个Array[Tuple2[Int, String]](在这种特殊情况下)。该: _*告诉编译器阵列的内容将被视为重复参数。

回答by retronym

Here's a general way to convert between various Scala collections.

这是在各种 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

See also this question describing collection.breakOut: Scala 2.8 breakOut

另请参阅此问题描述collection.breakOutScala 2.8 breakOut

CHALLENGE

挑战

Is it possible to adjust the implicits such that this works? Or would this only be possible if aswere added to Traversable?

是否可以调整隐式使其有效?或者这只有在as添加到时才有可能Traversable吗?

"foo".as[Vector]

回答by Tim Harper

Here's a way you can do it with a Scala implicit class:

这是您可以使用 Scala 隐式类实现的方法:

implicit class ToSortedMap[A,B](tuples: TraversableOnce[(A, B)])
                               (implicit ordering: Ordering[A]) {
  def toSortedMap =
    SortedMap(tuples.toSeq: _*)
}

Since Map[A,B] has an implicit path to a TraversableOnce[Tuple2[A, B]], the following works:

由于 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)

It will even work on a list of Tuple2s, similar to toMap:

它甚至可以处理类似于 toMap 的 Tuple2 列表:

scala> List(("c", 1), ("b", 3),("a", 6)).toSortedMap
res7: scala.collection.immutable.SortedMap[String,Int] = Map(a -> 6, b -> 3, c -> 1)

回答by Xavier Guihot

Starting Scala 2.13, via factory builders applied with .to(factory):

开始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")

回答by Alexander Kosenkov

Since internal data structures in implementations are completely different, you'll have to add elements one-by-one anyway. So, do it explicitly:

由于实现中的内部数据结构完全不同,因此无论如何您都必须一一添加元素。所以,明确地做:

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

var t = scala.collection.immutable.TreeMap[Int,String]()
t ++= m