我正在努力寻找列表的特殊映射。 如果我直接向您展示具体实例,您可以更容易地理解我的问题:
如何转换
(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的链式函数编程函数执行此类操作?
答案 0 :(得分: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)
答案 1 :(得分: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)))