Sequence of 4x card set card cards

I need a more concise way to convert a sequence of tuples into a map of map mappings ... As a signature, I get in the case of Tuple4 :

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

The following code shows my last ugly code that I used (type A to D arbitrary):

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

Note the use of head in val z .

It would be nice to have a more concise way only for Tuple4 , but also wondering how to generalize this to TupleN (N> = 2).

Is there a good approach in someone's head?

Thanks!

+7
source share
2 answers

The best I can come up with is

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

The generalization to tuples of a higher degree is completely straightforward ... just add additional nested applications mapValues ​​(_groupBy (_._ n) .... and adjust the correspondence of the final template accordingly.

Fully generalizing this as a function over sets of arbitrary arity, one could use it with HLists, but this would most likely be a much more difficult decision than what is needed here. I will leave this line of attack as an exercise for the questionnaire (or other commentators ;-).

+8
source

I suggest no shows in tuples:

 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) ) 
+1
source

All Articles