Search code examples
scaladictionaryfilterzip

Remove item in list if adjacent


I have a list of type Fruit.
I'm looking to remove APPLE, BANANA pairs, only if they're adjacent and in that order.

For example:

val basket: Fruitbasket = List(PEAR, APPLE, BANANA, CHERRY)

Reduced to:

LIST(PEAR, CHERRY)

Another example:

val basket2: Fruitbasket = List(PEAR, APPLE, PEAR, BANANA, CHERRY)

Would not reduce and remains as:

List(PEAR, APPLE, PEAR, BANANA, CHERRY)

I understand zipping with its tail is a way to compare adjacent elements, but what is the best way to filter and unzip?

basket.zip(basket.tail)

Solution

  • I guess you could just use a tail-recursive function and pattern matching:

    import scala.annotation.tailrec
    
    def filterOut(basket: List[String]): List[String] = {
    
        @tailrec
        def go(basket: List[String], acc: List[String] = Nil): List[String] = {
    
          basket match {
            case "APPLE" :: "BANANA" :: xs => go(xs, acc)
            case x :: xs => go(xs, x :: acc)
            case Nil => acc.reverse
          }
        }
    
        go(basket)
    }
    
    
    filterOut(List("PEAR", "APPLE", "BANANA", "CHERRY"))  // List("PEAR", "CHERRY")
    filterOut(List("PEAR", "APPLE", "PEAR", "BANANA", "CHERRY")) // List("PEAR", "APPLE", "PEAR", "BANANA", "CHERRY")