Naseebullah Safi Naseebullah Safi - 20 days ago 5
Scala Question

How can I add each element in first list with the corresponding list in Scala?

So I have a list so:

var data = List(
List(Some(313.062468), Some(27.847252), Some(29.847252)),
List(Some(301.873641), Some(42.884065), Some(89.847252)),
List(Some(332.373186), Some(53.509768), Some(10.847252))
)


How can I compute basic function like:



For each element of each list:

First row



Some(301.873641) - Some(313.062468) / Some(313.062468)
Some(332.373186) - Some(301.873641) / Some(301.873641)


Second Column



Some(42.884065) - Some(27.847252) / Some(27.847252)
Some(53.509768) - Some(42.884065) / Some(42.884065)


Third Column



Some(89.847252) - Some(29.847252) / Some(29.847252)
Some(10.847252) - Some(89.847252) / Some(89.847252)


Im currently stuck here



data.map(_.head).foreach {
case i => println(i)
}


This only prints the head of each nested list. I don't know how to get each element of the nested element and do the above calculation.

Result should be like this:

List(
List(Some(-0.03573991820699504), Some(0.5399747522663995), Some(88.847252) )
List(Some(0.10103414428290529), Some(0.24777742035415723), Some(9.847252) )
)

Answer

Transpose the list, then use .sliding(2) to get a rolling windows of the elements:

scala> def diffPercent(o1: Option[Double], o2: Option[Double]) = (o1, o2) match {
         case (Some(d1), Some(d2)) => Some((d2 - d1) / d1)  // need to handle d1 == 0 too
         case _ => None
       }
diffPercent: (o1: Option[Double], o2: Option[Double])Option[Double]

// sample value before the final operation
scala> data.transpose.map(_.sliding(2).toList) // .toList to show the values in REPL
res13: List[List[List[Some[Double]]]] = List(List(List(Some(313.062468), Some(301.873641)), List(Some(301.873641), Some(332.373186))), ...)

scala> data.transpose.map(_.sliding(2).map {
         case o1 :: o2 :: Nil => diffPercent(o1, o2)
         case _ => None // source has less than 2 elems
       }.toList).transpose  // transpose back the list
res17: List[List[Option[Double]]] = List(List(Some(-0.03573991820699504), Some(0.5399747522663995), Some(2.010235314125401)), List(Some(0.10103414428290529), Some(0.24777742035415723), Some(-0.8792700749489812)))