У меня есть a Seq
содержа объекты класса, который похож на это:
class A (val key: Int, ...)
Теперь я хочу преобразовать это Seq
к a Map
, использование key
значение каждого объекта как ключ и сам объект как значение. Так:
val seq: Seq[A] = ...
val map: Map[Int, A] = ... // How to convert seq to map?
Как может я делать это эффективно и изящным способом в Scala 2.8?
Сопоставьте свою Seq
и создайте последовательность кортежей. Затем используйте эти кортежи для создания Map
. Работает во всех версиях Scala.
val map = Map(seq map { a => a.key -> a }: _*)
Начиная с версии 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)
Еще одна вариация на тему 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))))