довольно просто, используя для-понимание и некоторый шаблон соответствия для destructure вещи:
val in = List((5, Map ("ABCD" -> Map("3200" -> 3, "3350.800" -> 4, "200.300" -> 3))),
(1, Map ("DEF" -> Map("1200" -> 32, "1320.800" -> 4, "2100" -> 3))))
case class Thing(a:Int, b:String, c:String, d:Int)
for { (index, m) <- in
(k,v) <-m
(innerK, innerV) <- v}
yield Thing(index, k, innerK, innerV)
//> res0: List[maps.maps2.Thing] = List(Thing(5,ABCD,3200,3),
// Thing(5,ABCD,3350.800,4),
// Thing(5,ABCD,200.300,3),
// Thing(1,DEF,1200,32),
// Thing(1,DEF,1320.800,4),
// Thing(1,DEF,2100,3))
Так давайте выберем часть для-понимания
(index, m) <- in
Это то же самое, как
t <- in
(index, m) = t
В первой строке t
последовательно будет установлено значение ea ch элемент in
. Поэтому t
является кортеж (Int, Map(...))
Паттен соответствия позволяет нам положить, что «Паттен» для кортежа на правой стороне и компилятор выбирает врозь кортеж, устанавливает index
к Int и m
на карте.
(k,v) <-m
Как и раньше это эквивалентно
u <-m
(k, v) = u
И на этот раз u
принимает каждый элемент карты. Которые снова являются кортежами ключа и значения. Таким образом, k
устанавливается последовательно каждому ключу и v
на значение.
И v
ваша внутренняя карта поэтому мы делаем то же самое снова с внутренней картой
(innerK, innerV) <- v}
Теперь у нас есть все, что нужно, чтобы создать класс дела. yield
просто говорит, что делает сборник того, что «дается» каждый раз через цикл.
yield Thing(index, k, innerK, innerV)
Под капотом, это просто приводит к набору карт/flatmaps
yield
только значение Thing(index, k, innerK, innerV)
Мы получаем один из тех, для каждого элемента v
v.map{x=>val (innerK, innerV) = t;Thing(index, k, innerK, innerV)}
, но есть внутренняя карта на элемент внешней карты
m.flatMap{y=>val (k, v) = y;v.map{x=>val (innerK, innerV) = t;Thing(index, k, innerK, innerV)}}
(flatMap
потому что мы получаем список списков, если мы просто сделали map
, и мы хотим, чтобы сгладить его только список элементов)
Кроме того, мы делаем один из тех, для каждого элемента в списке
in.flatMap (z => val (index, m) = z; m.flatMap{y=>val (k, v) = y;v.map{x=>val (innerK, innerV) = t;Thing(index, k, innerK, innerV)}}
Давайте сделаем это в _1
, _2
стиль-у.
in.flatMap (z=> z._2.flatMap{y=>y._2.map{x=>;Thing(z._1, y._1, x._1, x._2)}}}
, который производит точно такой же результат. Но разве это не понятно, как понимание?
Ваш пример вывода не имеет смысла. Можете ли вы написать его как тип scala? Список (5, ABCD, 3200, 3) или что-то в этом роде. –
Я хочу их как список классов case @ JustinPihony –