如何使用A值作为地图中的关键字将Seq [A]转换为Map [Int,A]?

时间:2010-05-27 21:22:25

标签: scala scala-2.8 scala-collections

我有一个Seq包含类的对象,如下所示:

class A (val key: Int, ...)

现在我想将此Seq转换为Map,使用每个对象的key值作为键,将对象本身作为值。所以:

val seq: Seq[A] = ...
val map: Map[Int, A] = ... // How to convert seq to map?

如何在Scala 2.8中以高效的方式有效地完成这项工作?

4 个答案:

答案 0 :(得分:63)

由于2.8 Scala已经.toMap,所以:

val map = seq.map(a => a.key -> a).toMap

或者如果你想避免构建一个中间序列的元组:

val map: Map[Int, A] = seq.map(a => a.key -> a)(collection.breakOut)

答案 1 :(得分:37)

映射到Seq并生成一系列元组。然后使用这些元组创建Map。适用于Scala的所有版本。

val map = Map(seq map { a => a.key -> a }: _*)

答案 2 :(得分:6)

另外一个2.8变化,为了更好的衡量,也是有效的:

scala> case class A(key: Int, x: Int)
defined class A

scala> val l = List(A(1, 2), A(1, 3), A(2, 1))
l: List[A] = List(A(1,2), A(1,3), A(2,1))

scala> val m: Map[Int, A] = (l, l).zipped.map(_.key -> _)(collection.breakOut)
m: Map[Int,A] = Map((1,A(1,3)), (2,A(2,1)))

请注意,如果您有重复的密钥,您将在创建地图时丢弃其中一些密钥!您可以使用groupBy创建一个地图,其中每个值都是一个序列:

scala> l.groupBy(_.key)
res1: scala.collection.Map[Int,List[A]] = Map((1,List(A(1,2), A(1,3))), (2,List(A(2,1))))

答案 3 :(得分:1)

由于scala知道将一个二元组转换为一个映射,你首先想要将你的seq转换为一个元组然后映射(如果它是int,则无关紧要,在我们的例子字符串中,字符串): / p>

一般算法是这样的:

  1. 对于Seq中的每个项目
  2. 项目 - >元组(键,值)
  3. 对于每个元组(键,值)
  4. 聚合到地图(键,值)
  5. 或者总结一下:

    步骤1:Seq - >两个元组

    步骤2:两个元组 - >图

    示例:

    case class MyData(key: String, value: String) // One item in seq to be converted to a map entry.
    
    // Our sequence, simply a seq of MyData
    val myDataSeq = Seq(MyData("key1", "value1"), MyData("key2", "value2"), MyData("key3", "value3")) // List((key1,value1), (key2,value2), (key3,value3))
    
    // Step 1: Convert seq to tuple
    val myDataSeqAsTuple = myDataSeq.map(myData => (myData.key, myData.value)) // List((key1,value1), (key2,value2), (key3,value3))
    
    // Step 2: Convert tuple of two to map.
    val myDataFromTupleToMap = myDataSeqAsTuple.toMap // Map(key1 -> value1, key2 -> value2, key3 -> value3)