2014-10-16 3 views
0

Я борюсь со специальным отображением списка. Это Propably проще для вас, чтобы понять мою проблему, если я покажу вам конкретный экземпляр непосредственно:Scala turn map [String, List [Int, Double]] to [Int, List [String, Double]]

Как превратить

(cat, List((0, 45.42), (1, 12.45), (2, 91.45)) 
(dog, List((0, 23.31), (1, 10.23), (2, 52.25)) 

в

(0, List((cat, 45.42)), List((dog, 23.31)) 
(1, List((cat, 12.45)), List((dog, 10.23)) 
(2, List((cat, 91.45)), List((dog, 52.25))) 

типы в основном:

[(String, List[(Int, Double)])] 

до

[(Int, List[(String, Double)])] 

Возможно ли выполнить такую ​​операцию, используя функции функционального программирования Scala?

ответ

1

Я не уверен, что это самый красивое идиоматическое решение, но это работает

val original: Map[String, List[(Int, Double)]] = Map(
    "cat" -> List((0, 45.42), (1, 12.45), (2, 91.45)), 
    "dog" -> List((0, 23.31), (1, 10.23), (2, 52.25)) 
) 

    val flatten = for { 
    (s, v) <- original 
    (i, d) <- v 
    } yield (i, s, d) 

    implicit class RichTuple2[A, B, C](t: (A, B, C)) { 
    def tail: (B, C) = (t._2, t._3) 
    } 

    val converted = flatten 
    .groupBy(_._1) 
    .mapValues(_.map(_.tail)) 

    println(converted) 
+0

если вы группа как 'выход (I, (s, d)) 'вам не понадобится' tail' –

1

Здесь:

scala> val ori: Map[String, List[(Int, Double)]] = Map(
    | "cat" -> List((0, 45.42), (1, 12.45), (2, 91.45)), 
    | "dog" -> List((0, 23.31), (1, 10.23), (2, 52.25)) 
    |) 
ori: Map[String,List[(Int, Double)]] = Map(cat -> List((0,45.42), (1,12.45), (2,91.45)), dog -> List((0,23.31), (1,10.23), (2,52.25))) 

scala> ori.foldLeft(Map[Int, List[(String, Double)]]()){ case (m, (k, v)) => 
    | v.foldLeft(m){ case(r, (i, d)) => r.updated(i, r.getOrElse(i, Nil) :+ (k, d)) } 
    | } 
res1: scala.collection.immutable.Map[Int,List[(String, Double)]] = Map(
     0 -> List((cat,45.42), (dog,23.31)), 
     1 -> List((cat,12.45), (dog,10.23)), 
     2 -> List((cat,91.45), (dog,52.25))) 
Смежные вопросы