Подтвердить что ты не робот

В Scala есть ли способ преобразовать два списка в карту?

У меня есть два списка: List[A] и List[B]. Я хочу Map[A,B], но мне нужна семантика zip. Так началось так:

var tuplesOfAB = listOfA zip listOfB

Теперь я не уверен, как построить Map из моего tuplesOfAB.

В качестве последующего вопроса я также хочу инвертировать мою карту, так что из Map[A,B] я могу создать Map[B,A]. Может кто-нибудь ударил меня ключом?

4b9b3361

Ответ 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)