Deden Bangkit Deden Bangkit - 1 month ago 7
Scala Question

Select and remove element on list with many term in Scala

I'm using

scala
for my logic program. I created list inside list with 5 elements each, for example:

val aList = List(List(2,2,8,5,6),List(8,4,5,6,7),List(1,8,1,2,1))
//the child list could be more than 3


I'm trying to get rid of non-duplicate elements with the following code:

def f(xs: List[Int]) = xs match {
case x0 :: x1 :: _ if x0 == x1 => Some(xs.takeWhile(_ == x0))
case _ => None
}

val aSelected = aList.flatMap(f)


and the result is:

aSelected: List(List(2,2),List(1,1,1))


But the problem is I need to include 8 if it's head, and while 8 is tail, 8 should be included with this terms:


  1. 8 in head will be included. ex:
    List(8,4,5,6,7) => List(8,4)

  2. 8 is besides duplicated elements on the left.ex:
    List(2,2,8,5,6) => List(2,2,8)

  3. 8 also the bridge for same value if it’s in between same numbers, so they could be included. ex.
    List(1,8,1,2,1) => List(1,8,1)



So for above example, the result should be:

aList = List(List(2,2,8),List(8,4),List(1,8,1))


This terms are a bit hard for me. Is there any possibilities to create code something like this?

Answer

Consider list one after other. on each list take while number is 8 or head of the current List.

Consider the case when you get only 8 and also consider the case when you will have only one number.

when you have just 8. ignore if you do not have next element. If you have next element then return the List(8, thatNumber)

When you have a number other than 8 then ignore if there is not next element. If you have next element then continue.

Everytime you get a partial list of (duplicates and 8's) drop that list from the main list and continue with the rest of the list.

  def foo(list: List[List[Int]]): List[List[Int]] = {
    def helper(currentList: List[Int], result: List[List[Int]]): List[List[Int]] = currentList match {
      case Nil => result
      case xList if xList.nonEmpty =>
        val xs = currentList.takeWhile(p => p == 8 || p == currentList.head)
        xs match {
          case Nil => result
          case 8 :: _ =>
            currentList match {
              case Nil => result
              case 8 :: x :: _ => helper(currentList.drop(2), result ::: List(8 :: x :: Nil))
            }
          case a :: Nil =>
            result
          case as =>
            helper(currentList.drop(as.length), result ::: List(as))
        }
    }
    list.flatMap(helper(_, List.empty[List[Int]]))
  }

Scala REPL

scala> val result = foo(aList)
result: List[List[Int]] = List(List(2, 2, 8), List(8, 4), List(1, 8, 1))