Coffee. On the rocks!

Scala foldLeft examples

Tue 22 April 2014

Here are alternate implementaions of some of the functions in Matt's wonderful post using scala's foldLeft

The get function takes a list and an integer index and returns the element in the list at the index. If the index is out of bounds it returns None

def get[A](lst: List[A], index: Int): Option[A] =
    lst.foldLeft[(Int, Option[A])]((-1, None))((r, c) => {
        if ((r._1+1) == index)
            (r._1+1, Some(lst(r._1+1)))
        else
            (r._1+1, r._2)
    })._2

The encode function takes a list and returns the freequency of them repeating. So passing List(1, 2, 2, 2, 2, 2, 3, 2, 2) to encode will return List((1, 1), (2, 5), (3, 1), (2, 2))

def encode[A](list: List[A]): List[(A, Int)] =
    list.tail.foldLeft(List[(A, Int)]((list.head, 1)))((r, c) => {
        if (r.last._1 == c)
            r.take(r.length-1) :+ (r.last._1, r.last._2 + 1)
        else
            r :+ (c, 1)
    })

The decode function is the opposite of encode. It would turn the list List((1, 1), (2, 5), (3, 1), (2, 2)) to List(1, 2, 2, 2, 2, 2, 3, 2, 2)

def decode[A](list: List[(A,Int)]): List[A] =
    list.foldLeft(List[A]()){ (r,c) =>
        r ++ List.fill[A](c._2)(c._1)
            }

The unique function takes a list and returns a list of the unique elements of the list. Its like taking a list, converting it to a set and then converting back to a list

def unique[A](list: List[A]): List[A] =
    list.foldLeft(List[A]())((r, c) => if (r.contains(c)) r else r :+ c)

The double function takes a list and returns a new list where each element of original list appears twice in a row.

def double[A](list: List[A]): List[A] =
    List.flatten(list.foldLeft(List[List[A]]())((r, c) => r :+ List[A](c, c)))

Or i can omit the flatten method and instead replace the :+ operator with ++, the list concatenation operator

def double[A](list: List[A]): List[A] =
    list.foldLeft(List[A]())((r, c) => r ++ List[A](c, c))

The group function takes a list list and an integer size and divides the list into chunks of the size size. So group(List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14), 3) would give List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9), List(10, 11, 12), List(13, 14))

def group[A](list: List[A], idx: Int): List[List[A]] =
    list.foldLeft(List[List[A]](), 0)((r, c) => {
        if (r._2 >= idx || r._2 == 0)
            (r._1 :+ List(c), 1)
        else
            (r._1.take(r._1.length-1) :+ (r._1.last :+ c), r._2+1)
    })._1

The pivot function takes a list and returns a tuple of 3 elements (<list of elements less than the 1st element of the list>, <1st element of the list>, <list of elements greater than or equal to the 1st element>)

def pivot[A <% Ordered[A]](list: List[A]): (List[A], A, List[A]) =
    list.tail.foldLeft(List[A](), list.head, List[A]())((r, c) => {
        if (c < r._2)
            (r._1 :+ c, r._2, r._3)
        else
            (r._1, r._2, r._3 :+ c)
    })

This entry was tagged as scala foldLeft

blog comments powered by Disqus