2011-02-15 36 views
7

我需要一個更簡潔的方式來元組序列轉化爲地圖的地圖的地圖...... 作爲一個簽名,我得到在Tuple4情況:4元組順序要地圖地圖的地圖

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

下面的代碼顯示了我最近醜陋代碼,我stucked用(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")) 

注意在使用。

如果只有Tuple4有一個更簡潔的方法將是很好的,但更有趣的是如何推廣到TupleN(N> = 2)。

有人在那裏有一個不錯的方法介意嗎?

謝謝!

回答

8

我能想出是最好的,

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

推廣到更高元數的元組是相當straightfoward ...只需添加mapValues的其他嵌套應用程序(_groupBy(_._ n)。...)並相應地調整最終模式匹配。

完全概括這是作爲任意ar的元組的函數可以使用HList,但這很可能是比這裏所需要的更重量級的解決方案。我將離開這一攻擊線路作爲提問者(或其他評論者;-)的練習。

+0

非常好的解決方案!謝謝! – 2011-02-15 19:11:57

1

我的元組建議implicits:

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) 
)