2014-10-16 57 views
0

我正在努力與列表的特殊映射。 這是propably您更容易理解我的問題,如果我告訴你,直接一個具體的實例:斯卡拉轉向地圖[字符串,列表[詮釋,雙]]至[詮釋,列表[字符串,雙]]

如何轉變

(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

如果組作爲'產量(我,(S,d ))''你不需要'尾巴' – 2014-10-17 11:09:30

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))) 
相關問題