2014-10-16 58 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))) 
相关问题