8

How to flatten nested tuples in scala

 3 years ago
source link: https://blog.knoldus.com/how-to-flatten-nested-tuples-in-scala/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

How to flatten nested tuples in scala

Reading Time: 2 minutes

In a project which I’ve been working on, I encountered a situation to flatten a nested tuple but couldn’t come up with a way to do so, hence out of curiosity I started googling about it and came to the following conclusion.

As for an example I had a structure something similar to the one mentioned below, though not identical:

xxxxxxxxxx
val structureToOperateOn = List(List("a1","a2","a3"), List("b1","b2","b3") , List("c1","c2","c3"), List(10,1,11))

and, supposedly I wanted to make structureToOperateOn something like this:

xxxxxxxxxx
"a1", "b1", "c1", 10
"a2", "b2", "c2", 1
"a3", "b3", "c3", 11

So the first thing that came to my mind was to use foldLeft:

xxxxxxxxxx
val operatedStructure = (structureToOperateOn.tail.foldLeft(structureToOperateOn.head)((a,b) => a zip b)).asInstanceOf[List[(((String,String),String),Int)]]

which resulted in something like this:

xxxxxxxxxx
List(((("a1","b1"),"c1"),10), ((("a2","b2"),"c2"),1), ((("a3","b3"),"c3"),11))

Next, I thought of flattening the tuples and came across Shapeless. Although I think scala should have something to flatten tuples, the best way it could be done as of now is to use Shapeless library. Anyways, this is how flattening tuples using Shapeless works:

xxxxxxxxxx
import shapeless._
import shapeless.ops.tuple.FlatMapper
import syntax.std.tuple._
object NestedTuple {
trait LowPriorityFlatten extends Poly1 {
implicit def default[T] = at[T](Tuple1(_))
}
object flatten extends LowPriorityFlatten {
implicit def caseTuple[P <: Product](implicit fm: FlatMapper[P, flatten.type]) =
at[P](_.flatMap(flatten))
}
val structureToOperateOn = List(List("a1","a2","a3"), List("b1","b2","b3") , List("c1","c2","c3"), List(10,1,11))
val operatedStructure = (structureToOperateOn.tail.foldLeft(structureToOperateOn.head)((a,b) => a zip b)).asInstanceOf[List[(((String,String),String),Int)]]
val flattenedTuples = operatedStructure map (tuple => flatten(tuple)) // This should be List((a1,b1,c1,10), (a2,b2,c2,1), (a3,b3,c3,11))
}

After messing around with nested tuples, I finally thought it’d be better to have an alternative way to get the required result instead of adding a new library in the project. Regardless, it could be very helpful in scenarios where you might get stuck and would want to ultimately flatten a tuple.

This was what I used as an alternative:

xxxxxxxxxx
val operatedStructure = structureToOperateOn.transpose

which resulted in:

xxxxxxxxxx
List(List("a1", "b1", "c1", 10), List("a2", "b2", "c2", 1), List("a3", "b3", "c3", 11))

So to conclude, you can use Shapeless in order to flatten complex nested tuples if need be.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK