Есть ли в Scala способ конвертировать два списка в карту? - PullRequest
26 голосов
/ 03 февраля 2010

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

var tuplesOfAB = listOfA zip listOfB

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

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

Ответы [ 4 ]

29 голосов
/ 03 февраля 2010

В 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]
15 голосов
/ 03 февраля 2010

Теперь, когда у вас есть список кортежей, легко превратить его в карту, написав Map(tuplesOfAB: _*). Запись : _* означает вызов перегрузки varargs с аргументами, взятыми из последовательности. Это выглядит как забавный синтаксис, но помогает думать, что varargs объявлены как Map[A,B](pairs: (A,B)*), а : _* - это аннотация типа для преобразования в varargs из-за общей части *.

Чтобы перевернуть карту m, используйте Map(m.map(_.swap): _*). В Scala карта также представляет собой набор пар. Это преобразует эти пары путем замены элементов и передачи их в конструктор Map.

5 голосов
/ 03 февраля 2010

Есть еще один способ сделать это, помимо уже показанного.Здесь:

Map() ++ tuplesOfAB
4 голосов
/ 19 мая 2012
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)
...