地图地图的4元组序列

时间:2011-02-15 16:47:28

标签: scala

我需要一种更简洁的方法将一系列元组转换为地图地图的地图...... 作为签名,我得到Tuple4

def tuple4Seq2MapOfMaps[A,B,C,D](seq: Seq[(A,B,C,D)]): Map[A,Map[B,Map[C,D]]]

以下代码显示了我最近的丑陋的代码,我坚持使用A D任意对象:

type A = Int
type B = Double
type C = String
type D = Boolean
val tupleSeq = Seq[(A,B,C,D)](
  (1,1.0D,"a",true),
  (1,1.0D,"b",true),
  (1,1.0D,"c",false)
)
val x = tupleSeq.groupBy{ _._1 }.map{ case (k,s) => (k,s.map{ x => (x._2,x._3,x._4) }) }
val y = x.map{ case (k,s) => (k,s.groupBy{_._1}.map{ case (k,s) => (k,s.map{ x => (x._2,x._3) }) }) }
val z = y.map{ case (k1,m) => (k1,m.map{ case (k2,s1) => (k2,s1.groupBy{_._1}.map{ case (k3,s2) => (k3,s2.map{ _._2 }.head) }) }) }

val m = z(1)(1.0D)
println(m("b"))

请注意在head使用val z

仅对Tuple4采用更简洁的方式会更好,但更有趣的是如何将其概括为TupleN(N> = 2)。

在某些人心中有没有一个很好的方法呢?

谢谢!

2 个答案:

答案 0 :(得分:8)

我能想到的最好的是,

tupleSeq.groupBy(_._1).
  mapValues(_.groupBy(_._2).
    mapValues(_.groupBy(_._3).
      mapValues{ case Seq(p) => p._4 }))

推广到更高级别的元组是非常直接的...只需添加mapValues的其他嵌套应用程序(_groupBy(_._ n)....并相应地调整最终模式匹配。

使用HLists可以将这作为任意arity元组的函数完全概括,但这很可能是比这里需要的更重要的解决方案。我将这一攻击线留作提问者(或其他评论者; - )的练习。

答案 1 :(得分:1)

我建议对元组进行暗示:

implicit def Tup3Cut[A,B,C](tup: (A,B,C)) = new {
  def decapitate = (tup._2,tup._3)
}
implicit def Tup4Cut[A,B,C,D](tup: (A,B,C,D)) = new {
  def decapitate = (tup._2,tup._3,tup._4)
}

val tupleSeq = Seq((1,1d,"a",true),(1,1d,"b",true),(1,1d,"c",false),(1,2d,"c",true))

tupleSeq.groupBy(_._1).mapValues(
  _.map(_.decapitate).groupBy(_._1).mapValues(_.map(_.decapitate).toMap)
)