Как преобразовать Seq[A] в карту[Int, A], используя значение A в качестве ключа на карте?
у меня есть 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 ответов
карта за свои 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
или если вы gung ho об избежании построения промежуточной последовательности кортежей:
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))))
как scala знает, чтобы преобразовать кортеж из двух в карту, вы сначала хотите преобразовать свой seq в кортеж, а затем отобразить так (не имеет значения, если это int, в нашем случае строка, строка):
общий алгоритм такой:
- для каждого элемента в Seq
- товар --> кортежей(ключ, значение)
- для каждого кортежа (ключ, значение)
- Aggregate to Map (ключ,значение)
или подытожить:
Шаг 1: Seq --> Кортеж два
Шаг 2: кортеж из двух -- > Map
пример:
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)