В Scala есть ли способ преобразовать два списка в карту?
У меня есть два списка: List[A]
и List[B]
. Я хочу Map[A,B]
, но мне нужна семантика zip
. Так началось так:
var tuplesOfAB = listOfA zip listOfB
Теперь я не уверен, как построить Map
из моего tuplesOfAB
.
В качестве последующего вопроса я также хочу инвертировать мою карту, так что из Map[A,B]
я могу создать Map[B,A]
. Может кто-нибудь ударил меня ключом?
Ответы
Ответ 1
В 2.8 это действительно просто, используя функциональность CanBuildFrom
(как описано Daniel) и используя breakOut
с типом инструкции компилятору относительно того, какой должен быть тип результата:
import scala.collection.breakOut
val m = (listA zip listB)(breakOut): Map[A,B]
Следующие действия также будут работать:
val n: Map[A,B] = (listA zip listB)(breakOut)
И (как указал EastSun ниже), это было добавлено в библиотеку как toMap
val o = (listA zip listB).toMap
Что касается изменения карты, вы можете сделать:
val r = m.map(_.swap)(breakOut): Map[B, A]
Ответ 2
Теперь, когда у вас есть список кортежей, легко сделать его на карте, написав Map(tuplesOfAB: _*)
. Обозначение : _*
означает вызов перегрузки varargs с аргументами, взятыми из последовательности. Это похоже на забавный бит синтаксиса, но это помогает думать, что varargs объявляются как Map[A,B](pairs: (A,B)*)
, а : _*
- это аннотация для преобразования в varargs из-за общей части *
.
Чтобы отменить карту m
, используйте Map(m.map(_.swap): _*)
. В scala карта также представляет собой набор пар. Это преобразует эти пары, заменяя элементы и передавая их конструктору Map.
Ответ 3
Есть еще один способ сделать это, помимо тех, которые уже показаны. Здесь:
Map() ++ tuplesOfAB
Ответ 4
scala> List( "a", "f", "d") zip List(7, 5, 4, 8) toMap
res0: scala.collection.immutable.Map[java.lang.String,Int] = Map(a -> 7, f -> 5, d -> 4)