Search code examples
scalafold

Scala conditional fold in Tuple(int,int)


I have a list of tuples (int,int) such as

(100,3), (130,3), (160,1), (180,2), (200,2)

I want to foldRight or something efficient where the neighbors are compared. For ((A1,A2),(B1,B2)), we do a merge only when A2 is less than or equal to B2. Otherwise, we do not fold the list at that instance. If we merge, we retain (A1,A2) and add a count field. The sample output is

(100,3,2) and (160,1,3)

here 2 and 3 are the weight of the observations folded to this one observation.

(100,3), (130,3)

will lead to (100,3,2)

while

(160,1), (180,2), (200,2)

will lead to (160,1,3)

Any idea how to write it in scala functional style?


Solution

  • scala>def conditionalFold(in: List[(Int, Int)]): List[(Int, Int, Int)] =
     |     in.foldLeft(Nil: List[(Int, Int, Int)]) { (acc, i) =>
     |       acc match {
     |         case Nil =>
     |           (i._1, i._2, 1) :: Nil
     |         case head :: tail =>
     |           if (i._2 >= head._2)
     |             (head._1, head._2, head._3 + 1) :: tail
     |           else
     |             (i._1, i._2, 1) :: head :: tail
     |       }
     |     }.reverse
    conditionalFold: (in: List[(Int, Int)])List[(Int, Int, Int)]
    
    scala>   println(conditionalFold(List((100, 3), (130, 3), (160, 1), (180, 2), (200, 2))))
    List((100,3,2), (160,1,3))
    
    scala>   println(conditionalFold(List((100,3), (130,3))))
    List((100,3,2))
    
    scala>   println(conditionalFold(List((160,1), (180,2), (200,2))))
    List((160,1,3))