Как преобразовать Seq [A] в карту [Int, A], используя значение A в качестве ключа на карте? - PullRequest
37 голосов
/ 28 мая 2010

У меня есть Seq, содержащий объекты класса, который выглядит так:

class A (val key: Int, ...)

Теперь я хочу преобразовать это Seq в Map, используя значение key каждого объекта в качестве ключа и сам объект в качестве значения. Итак:

val seq: Seq[A] = ...
val map: Map[Int, A] = ... // How to convert seq to map?

Как я могу сделать это эффективно и элегантно в Scala 2.8?

Ответы [ 4 ]

65 голосов
/ 28 мая 2010

С версии 2.8 у Scala было .toMap, поэтому:

val map = seq.map(a => a.key -> a).toMap

или если вы не хотите создавать промежуточную последовательность кортежей:

val map: Map[Int, A] = seq.map(a => a.key -> a)(collection.breakOut)
38 голосов
/ 28 мая 2010

Отобразите карту над Seq и создайте последовательность кортежей. Затем используйте эти кортежи для создания Map. Работает во всех версиях Scala.

val map = Map(seq map { a => a.key -> a }: _*)
6 голосов
/ 28 мая 2010

Еще один вариант 2,8, для хорошей меры, также эффективен:

scala> case class A(key: Int, x: Int)
defined class A

scala> val l = List(A(1, 2), A(1, 3), A(2, 1))
l: List[A] = List(A(1,2), A(1,3), A(2,1))

scala> val m: Map[Int, A] = (l, l).zipped.map(_.key -> _)(collection.breakOut)
m: Map[Int,A] = Map((1,A(1,3)), (2,A(2,1)))

Обратите внимание, что если у вас есть дубликаты ключей, некоторые из них будут отброшены при создании карты! Вы можете использовать groupBy для создания карты, где каждое значение является последовательностью:

scala> l.groupBy(_.key)
res1: scala.collection.Map[Int,List[A]] = Map((1,List(A(1,2), A(1,3))), (2,List(A(2,1))))
1 голос
/ 07 февраля 2018

Поскольку scala знает, как преобразовать кортеж из двух в карту, вы сначала захотите преобразовать свой seq в кортеж, а затем отобразить его (не имеет значения, является ли оно int, в нашем случае string, string):

Общий алгоритм таков:

  1. Для каждого элемента в сек.
  2. Item -> Tuple (ключ, значение)
  3. Для каждого кортежа (ключ, значение)
  4. Агрегировать на карту (ключ, значение)

Или подвести итог:

Шаг 1: Seq -> кортеж из двух

Шаг 2: Кортеж из двух -> Карта

Пример: * * один тысяча двадцать-одна

case class MyData(key: String, value: String) // One item in seq to be converted to a map entry.

// Our sequence, simply a seq of MyData
val myDataSeq = Seq(MyData("key1", "value1"), MyData("key2", "value2"), MyData("key3", "value3")) // List((key1,value1), (key2,value2), (key3,value3))

// Step 1: Convert seq to tuple
val myDataSeqAsTuple = myDataSeq.map(myData => (myData.key, myData.value)) // List((key1,value1), (key2,value2), (key3,value3))

// Step 2: Convert tuple of two to map.
val myDataFromTupleToMap = myDataSeqAsTuple.toMap // Map(key1 -> value1, key2 -> value2, key3 -> value3)
...