Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to transform Scala collection of Option[X] to collection of X

I'm starting to explore Scala, and one of the things I'm intrigued by is the Option type and the promise of being able to eliminate null related errors.

However I haven't been able to work out how to transform a list (or other collection) of, say, Option[String], to a collection of String (obviously filtering out any values that are None).

In other words, how do I get from this:

List[Option[Int]] = List(Some(1)) 

... to this:

List[Int] = List(1) 

I'm using Scala 2.8 if that has any impact on the answer.

like image 986
npad Avatar asked Jan 19 '11 01:01

npad


People also ask

What is getOrElse in Scala?

As we know getOrElse method is the member function of Option class in scala. This method is used to return an optional value. This option can contain two objects first is Some and another one is None in scala. Some class represent some value and None is represent a not defined value.

How do I use options in Scala?

The Option in Scala is referred to a carrier of single or no element for a stated type. When a method returns a value which can even be null then Option is utilized i.e, the method defined returns an instance of an Option, in place of returning a single object or a null.

What is some function in Scala?

Scala some class returns some value if the object is not null, it is the child class of option. Basically, the option is a data structure which means it can return some value or None. The option has two cases with it, None and Some. We can use this with the collection.


2 Answers

val list1 = List(Some(1), None, Some(2)) val list2 = list1.flatten // will be: List(1,2) 
like image 100
Madoc Avatar answered Sep 26 '22 19:09

Madoc


For educational purposes, you might like some alternatives:

scala> val list1 = List(Some(1), None, Some(2)) list1: List[Option[Int]] = List(Some(1), None, Some(2))  scala> list1 flatten res0: List[Int] = List(1, 2)  // Expanded to show the implicit parameter scala> list1.flatten(Option.option2Iterable) res1: List[Int] = List(1, 2)  scala> list1 flatMap (x => x) res2: List[Int] = List(1, 2)  scala> list1 flatMap Option.option2Iterable res3: List[Int] = List(1, 2)  // collect is a simultaneous map + filter scala> list1 collect { case Some(x) => x } res4: List[Int] = List(1, 2) 

With Scalaz, you can perform a slightly different operation called sequence, that returns Option[List[Int]].

scala> import scalaz._; import Scalaz._ import scalaz._ import Scalaz._  scala> val list1: List[Option[Int]] = List(Some(1), None, Some(2))  list1: List[Option[Int]] = List(Some(1), None, Some(2))  scala> list1.sequence                                               res1: Option[List[Int]] = None  scala> val list2: List[Option[Int]] = List(Some(1), Some(2))          list2: List[Option[Int]] = List(Some(1), Some(2))  scala> list2.sequence res2: Option[List[Int]] = Some(List(1, 2)) 
like image 36
retronym Avatar answered Sep 25 '22 19:09

retronym