Reputation: 146
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
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
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
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