代码之家  ›  专栏  ›  技术社区  ›  Jesper

如何使用值a作为映射中的键将seq[a]转换为map[int,a]?

  •  33
  • Jesper  · 技术社区  · 14 年前

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

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

    现在我想转换这个 SEQ 到A Map ,使用 key 每个对象的值作为键,对象本身作为值。所以:

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

    在scala 2.8中,我如何高效、优雅地完成这项工作?

    4 回复  |  直到 6 年前
        1
  •  32
  •   Daniel Spiewak    14 年前

    在你的地图上 Seq 生成一个元组序列。然后使用这些元组创建 Map . 适用于所有版本的scala。

    val map = Map(seq map { a => a.key -> a }: _*)
    
        2
  •  58
  •   Seth Tisue Arthur Hjorth    10 年前

    从2.8开始,斯卡拉 .toMap 因此:

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

    或者,如果你在努力避免构造一个中间的元组序列:

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

        3
  •  6
  •   retronym    14 年前

    另外一个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))))
    
        4
  •  1
  •   Tomer Ben David    6 年前

    正如scala知道要将一个二元组转换为一个映射,您首先要将seq转换为一个元组,然后再转换为map so(在我们的case string中,string不重要):

    一般的算法是:

    1. 对于seq中的每个项目
    2. 项-->元组(键,值)
    3. 对于每个元组(键、值)
    4. 聚合到映射(键,值)

    或者总结一下:

    步骤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)