Scala - как построить неизменяемую карту из коллекции Tuple2s? - PullRequest
6 голосов
/ 24 июля 2010

В 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 типа Tuple2s для построения карты, например,

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 ]

10 голосов
/ 24 июля 2010

Используя 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 многое было улучшено.

4 голосов
/ 24 июля 2010

Хотя есть некоторые ответы, которые дают хороший совет, вот то, что я думаю, наиболее близко к исходному коду Python.необходимо преобразовать диапазоны в списки в первом назначении:

// Scala 2.7
val listOfTuples = (0 until 10).toList zip (for (x <- 0 until 10) yield -x).toList
val theMap = Map(listOfTuples:_*)
2 голосов
/ 24 июля 2010

Я не могу оставить комментарий к принятому ответу (пока недостаточно репутации), но предлагаемое решение для Scala 2.7 слишком сложное:

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

«Карта» ничего не делает, она конвертирует 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)
2 голосов
/ 24 июля 2010

Есть несколько вариантов. Во-первых (но не рекомендуется, IMO), вы можете преобразовать List в переменные, используя 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...