rosy
rosy

Reputation: 146

How to remove null cases from a List(List(List())) in scala?

I want only valid values from a List(List(List())), for example,

List(List(List(())), List(List(())), List(List(())), List(List(())), List(List(())), List(List(book eraser -> pen , confidence :66.0)))
List(List(List(())), List(List(Ink -> pen eraser , confidence :100.0)), List(List(())), List(List(pen Ink -> eraser , confidence :100.0)), List(List(())), List(List(Ink eraser -> pen , confidence :100.0)))

I need only the inside strings,

book eraser -> pen , confidence :66.0
Ink -> pen eraser , confidence :100.0
pen Ink -> eraser , confidence :100.0
Ink eraser -> pen , confidence :100.0

Upvotes: 1

Views: 410

Answers (3)

Rex Kerr
Rex Kerr

Reputation: 167871

If you write a recursive method like so, you can pull out the strings regardless of the nesting. (flatten only works if everything is nested to the same depth.)

def allStrings[A](xs: List[A]): List[String] = {
  val ss = List.newBuilder[String]
  def decompose(xs: List[_]) { xs match {
    case (s: String) :: more => ss += s; decompose(more)
    case (l: List[_]) :: more => decompose(l); decompose(more)
    case x :: more => decompose(more)
    case Nil =>
  }}
  decompose(xs)
  ss.result
}

That said, this is a weird way to store data.

(Note: all the decompose(more) calls are tail-recursive, so you won't have stack overflow problems. decompose(l) is normal recursion, so if your lists are nested more than a thousand or so layers deep, you probably want to do it a different way (e.g. heap-based breadth-first search).)

Upvotes: 2

mohit
mohit

Reputation: 4999

I had to add collect to @Gabriele answer to get the desired result.

scala> List(List(List(())), List(List("Ink -> pen eraser , confidence :100.0")), List(List(())),List(List("pen Ink -> eraser , confidence :100.0")), List(List(())), List(List("Ink eraser -> pen , confidence :100.0")))
res0: List[List[List[Any]]] = List(List(List(())), List(List(Ink -> pen eraser ,confidence :100.0)),List(List(())), List(List(pen Ink -> eraser , confidence :100.0)), List(List(())),List(List(Ink eraser -> pen , confidence :100.0)))

scala> res0.flatten.flatten.collect{case str: String => str}
res1: List[String] = List(Ink -> pen eraser , confidence :100.0, pen Ink -> eraser , confidence :100.0, Ink eraser -> pen , confidence :100.0)

scala> val a = List(List(List(())), List(List("Ink -> pen eraser , confidence :100.0")), List(List(())), List(List("pen Ink -> eraser , confidence :100.0")), List(List(())), List(List("Ink eraser -> pen , confidence :100.0")))
scala> res0.flatten.flatten.collect{case str: String => str}
res4: List[String] = List(Ink -> pen eraser , confidence :100.0, pen Ink -> eraser , confidence :100.0, Ink eraser -> pen , confidence :100.0)

Instead of collect, you can also use filter(_ != ())

Upvotes: 1

Gabriele Petronella
Gabriele Petronella

Reputation: 108101

The example you provided isn't exactly clear, but I looks like a couple of flatten might help:

val a = List(List(List()), List(List("book eraser -> pen , confidence :66.0")), List(List())) 
a.flatten.flatten // List[String] = List(book eraser -> pen , confidence :66.0)   

Upvotes: 2

Related Questions