puz*_*ent 5 ocaml haskell functional-programming scala
我有点卡在这个问题上.我觉得我在"倒退",这让我感到困惑.
我有一个Map[Long, Seq[String]]我想转换成一个Seq[Map[Long, String]].走向另一个方向相当简单,因为我们可以将元素组合在一起,但是,我不确定如何以功能方式将它们分开.
所以,
val x = Map(1 -> List("a","b","c"), 2 -> List("d", "e"), 3 -> List("f"))
Run Code Online (Sandbox Code Playgroud)
应该成为
List(Map(1 -> "a", 2 -> "d", 3 -> "f"), Map(1 -> "b", 2 -> "e"), Map(1 -> "c"))
Run Code Online (Sandbox Code Playgroud)
我正在考虑使用x.partition然后在每个结果元组上递归,但我不确定我要分区的内容:/
我正在用scala编写,但任何功能性答案都是受欢迎的(语言不可知).
在Haskell:
> import qualified Data.Map as M
> import Data.List
> m = M.fromList [(1,["a","b","c"]), (2,["d","e"]), (3,["f"])]
> map M.fromList . transpose . map (\(i,xs) -> map ((,) i) xs) . M.toList $ m
[fromList [(1,"a"),(2,"d"),(3,"f")],fromList [(1,"b"),(2,"e")],fromList [(1,"c")]]
Run Code Online (Sandbox Code Playgroud)
M.toList和M.fromList地图转换为关联配对,和背部的列表.
map ((,) i) xs与[(i,x) | x<-xs]添加(i,...)到每个元素相同.
transpose 与矩阵转置类似,在列表列表中交换"行"和"列".
transpose从这个SO答案中借用一个简洁的方法,这是另一种方法:
def transpose[A](xs: List[List[A]]): List[List[A]] = xs.filter(_.nonEmpty) match {
case Nil => Nil
case ys: List[List[A]] => ys.map{ _.head }::transpose(ys.map{ _.tail })
}
transpose[(Int, String)](
x.toList.map{ case (k, v) => v.map( (k, _) ) }
).map{ _.toMap }
// Res1: List[scala.collection.immutable.Map[Int,String]] = List(
// Map(1 -> a, 2 -> d, 3 -> f), Map(1 -> b, 2 -> e), Map(1 -> c)
// )
Run Code Online (Sandbox Code Playgroud)