Scala - convert List of Lists into a single List: List[List[A]] to List[A]

34,647

Solution 1

List has the flatten method. Why not use it?

List(List(1,2), List(3,4)).flatten
> List(1,2,3,4)

Solution 2

.flatten is obviously the easiest way, but for completeness you should also know about flatMap

 val l = List(List(1, 2), List(3, 4))
 println(l.flatMap(identity))

and the for-comprehension equivalent

 println(for (list <- l; x <- list) yield x)

flatten is obviously a special case of flatMap, which can do so much more.

Solution 3

Given the above example, I'm not sure you need recursion. Looks like you want List.flatten instead.

e.g.

scala> List(1,2,3)
res0: List[Int] = List(1, 2, 3)

scala> List(4,5,6)
res1: List[Int] = List(4, 5, 6)

scala> List(res0,res1)
res2: List[List[Int]] = List(List(1, 2, 3), List(4, 5, 6)) 

scala> res2.flatten
res3: List[Int] = List(1, 2, 3, 4, 5, 6)

Solution 4

If your structure can be further nested, like:

List(List(1, 2, 3, 4, List(5, 6, List(7, 8))))

This function should give you the desire result:

def f[U](l: List[U]): List[U] = l match {
  case Nil => Nil
  case (x: List[U]) :: tail => f(x) ::: f(tail)
  case x :: tail => x :: f(tail)
}
Share:
34,647
A Far
Author by

A Far

Updated on July 09, 2022

Comments

  • A Far
    A Far almost 2 years

    What's the best way to convert a List of Lists in scala (2.9)?

    I have a list:

    List[List[A]]
    

    which I want to convert into

    List[A]
    

    How can that be achieved recursively? Or is there any other better way?

  • andres.santana
    andres.santana over 9 years
    How will you flatten this List(1, List(2,3), 4, List(5,6,7)) Expected result is List(1, 2, 3, 4, 5,6,7)
  • Jan
    Jan about 9 years
    the above list is heterogeneous, flatten wont work there. You can do something like: List(1, List(2,3), 4, List(5,6,7)).collect{case i:Int => List(i); case l @ a :: b => l}.flatten
  • Andy Hayden
    Andy Hayden over 8 years
    If you want to add in some data during the map this is what you want.
  • jwvh
    jwvh about 6 years
    How is this answer different from the answer given by Dave Griffith 5 years ago? (Other than the fact that the older answer is cleaner and more concise.)
  • Robin
    Robin about 6 years
    You are right, almost the same. I believe that mine is easier to understand or give you some hit for the underline. I am passing a identity function instead of identity keyword. Hope that it makes sense for you
  • akki
    akki over 5 years
    Will ll.flatMap(_) also do the same thing as ll.flatMap(_.map(o=>o)) ?
  • srzhio
    srzhio over 4 years
    @akki, why don't you try it yourself? It's a moment’s work :). I bet it won't work. Since "underscore" in function literal doesn't describe "identity" function, it means an argument of that function that should be used to describe some logic. But _ => _ will not work either.
  • F. P. Freely
    F. P. Freely about 3 years
    Interestingly, IDEA suggested I change listOfLists.flatMap(identity) to listOfLists.flatten.