This is an excerpt from the Scala Cookbook (partially modified for the internet). This is Recipe 10.15, “How to Flatten a List of Lists in Scala with flatten
”
Problem
You have a list of lists (a sequence of sequences) and want to create one list (sequence) from them.
Solution
Use the flatten
method to convert a list of lists into a single list. To demonstrate this, first create a list of lists:
scala> val lol = List(List(1,2), List(3,4)) lol: List[List[Int]] = List(List(1, 2), List(3, 4))
Calling the flatten
method on this list of lists creates one new list:
scala> val result = lol.flatten result: List[Int] = List(1, 2, 3, 4)
As shown, flatten
does what its name implies, flattening the lists held inside the outer list into one resulting list.
Though I use the term “list” here, the flatten
method isn’t limited to a List
; it works with other sequences (Array, ArrayBuffer, Vector, etc.) as well:
scala> val a = Array(Array(1,2), Array(3,4)) a: Array[Array[Int]] = Array(Array(1, 2), Array(3, 4)) scala> a.flatten res0: Array[Int] = Array(1, 2, 3, 4)
In the real world, you might use flatten
to convert a list of couples attending a wedding into a single list of all people attending the wedding. Calling flatten
on a List[List[String]]
does the job:
scala> val couples = List(List("kim", "al"), List("julia", "terry")) couples: List[List[String]] = List(List(kim, al), List(julia, terry)) scala> val people = couples.flatten people: List[String] = List(kim, al, julia, terry)
If you really want to have fun, capitalize each element in the resulting list and then sort the list:
scala> val people = couples.flatten.map(_.capitalize).sorted people: List[String] = List(Al, Julia, Kim, Terry)
This helps to demonstrate the power of the Scala collections methods. (Imagine trying to write that code with only a for
loop.)
In a social-networking application, you might do the same thing with a list of friends, and their friends:
val myFriends = List("Adam", "David", "Frank") val adamsFriends = List("Nick K", "Bill M") val davidsFriends = List("Becca G", "Kenny D", "Bill M") val friendsOfFriends = List(adamsFriends, davidsFriends)
Because friendsOfFriends
is a list of lists, you can use flatten
to accomplish many tasks with it, such as creating a unique list of the friends of your friends:
scala> val uniqueFriendsOfFriends = friendsOfFriends.flatten.distinct uniqueFriendsOfFriends: List[String] = List(Nick K, Bill M, Becca G, Kenny D)
More on flatten in Scala
The flatten
method is useful in at least two other situations. First, because a String
is a sequence of Char
, you can flatten a list of strings into a list of characters:
scala> val list = List("Hello", "world") list: List[java.lang.String] = List(Hello, world) scala> list.flatten res0: List[Char] = List(H, e, l, l, o, w, o, r, l, d)
Second, because an Option
can be thought of as a container that holds zero or one elements, flatten
has a very useful effect on a sequence of Some
and None
elements. It pulls the values out of the Some
elements to create the new list, and drops the None
elements:
scala> val x = Vector(Some(1), None, Some(3), None) x: Vector[Option[Int]] = Vector(Some(1), None, Some(3), None) scala> x.flatten res1: Vector[Int] = Vector(1, 3)
(You’ll also see a similar benefit when using the Scala flatMap method.)
this post is sponsored by my books: | |||
#1 New Release |
FP Best Seller |
Learn Scala 3 |
Learn FP Fast |