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

scala-如何从tuple2集合构建不可变映射?

  •  6
  • I82Much  · 技术社区  · 15 年前

    在python中,可以从一个可迭代的元组集合构造字典:

    >>> listOfTuples = zip(range(10), [-x for x in range(10)])
    >>> listOfTuples
    [(0, 0), (1, -1), (2, -2), (3, -3), (4, -4), (5, -5), (6, -6), (7, -7), (8, -8), (9, -9)]
    >>> theDict = dict(listOfTuples)
    >>> theDict
    {0: 0, 1: -1, 2: -2, 3: -3, 4: -4, 5: -5, 6: -6, 7: -7, 8: -8, 9: -9}
    >>> 
    

    有等价的scala语法吗?我看到您可以使用varargs类型的tuple2数量来构造一个映射,例如。

    scala> val theMap = Map((0,0),(1,-1))
    theMap: scala.collection.immutable.Map[Int,Int] = Map((0,0), (1,-1))
    
    scala> theMap(0)
    res4: Int = 0
    
    scala> theMap(1)
    res5: Int = -1
    
    scala> val tuplePairs = List((0,0),(1,-1))
    tuplePairs: List[(Int, Int)] = List((0,0), (1,-1))
    
    scala> val mapFromIterable = Map(tuplePairs)
    <console>:6: error: type mismatch;
     found   : List[(Int, Int)]
     required: (?, ?)
           val mapFromIterable = Map(tuplePairs)
                                     ^
    

    我可以手动循环并分配每个值,但似乎必须有更好的方法。

    scala> var theMap:scala.collection.mutable.Map[Int,Int] = scala.collection.mutable.Map()   
    theMap: scala.collection.mutable.Map[Int,Int] = Map()
    
    scala> tuplePairs.foreach(x => theMap(x._1) = x._2)                                     
    
    scala> theMap
    res13: scala.collection.mutable.Map[Int,Int] = Map((1,-1), (0,0))
    
    4 回复  |  直到 15 年前
        1
  •  10
  •   Michael Mior    7 年前

    使用scala 2.8.0 final,您可以这样做:

    
    scala> val tuplePairs = List((0,0),(1,-1))
    tuplePairs: List[(Int, Int)] = List((0,0), (1,-1))
    
    scala> tuplePairs.toMap
    res0: scala.collection.immutable.Map[Int,Int] = Map((0,0), (1,-1))
    

    如果您使用scala 2.7.7,那么可以这样做,作为您使用的方法的替代:

    
    scala> val tuplePairs = List((0,0),(1,-1))
    tuplePairs: List[(Int, Int)] = List((0,0), (1,-1))
    
    scala> Map(tuplePairs: _*)
    res2: scala.collection.immutable.Map[Int,Int] = Map(0 -> 0, 1 -> -1)
    

    但是正如你所看到的,在2.8.0版本中,事情已经有了很大的改进。

        2
  •  4
  •   mkneissl    15 年前

    虽然有一些答案给出了很好的建议,但这里是我认为最接近原始Python代码的答案。

    // Scala 2.8
    val listOfTuples = (0 until 10) zip (for (x <- 0 until 10) yield -x)
    val theMap = Map(listOfTuples:_*)
    

    scala 2.7没有 zip 但是,对于范围,您必须在第一个分配中将范围转换为列表:

    // Scala 2.7
    val listOfTuples = (0 until 10).toList zip (for (x <- 0 until 10) yield -x).toList
    val theMap = Map(listOfTuples:_*)
    
        3
  •  2
  •   Jackson Davis    15 年前

    有几种选择。首先(但我不建议),你可以转换 List 变为varargs list:_* 或者,您可以使用类似于++函数的功能将值列表添加到映射中(这也是map.apply所做的)。

    scala> (Map[Int,Int]()) ++ List((1,2),(3,4))
    res4: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2, 3 -> 4)
    
    scala> Map(List((1,2),(3,4)):_*)
    res5: scala.collection.immutable.Map[Int,Int] = Map(1 -> 2, 3 -> 4)
    
        4
  •  2
  •   bseibold    15 年前

    我不能对接受的答案发表评论(还没有足够的声誉),但针对scala 2.7的建议解决方案过于复杂:

    scala> Map() ++ (tuplePairs map (t => (t._1,t._2)))
    res2: scala.collection.immutable.Map[Int,Int] = Map(0 -> 0, 1 -> -1)
    

    “map”没有做任何事情,它将tuple2转换成tuple2。 这就足够了:

    scala> Map() ++ tuplePairs
    res3: scala.collection.immutable.Map[Int,Int] = Map(0 -> 0, 1 -> -1)
    

    在我看来,使用map.empty会更好:

    scala> Map.empty ++ tuplePairs
    res4: scala.collection.immutable.Map[Int,Int] = Map(0 -> 0, 1 -> -1)
    
    推荐文章