Add Option[T] to Vector[T]

Viewed 232

What is the best practice to perform such an operation? Add T to Vector[T] if T is Some[T] otherwise do nothing. This ugly thing works

val v: Vector[Int] = Vector(1, 2, 3) ++ Some(5).toSeq

But converting an Option to a Seq is far from intuitive. I was thinking of defining an implicit for Vector and Option but I was wondering if there is something out of the box I can use.

I would expect for something like this to work

   val v: Vector[Int] = Vector(1, 2, 3) :+ Some(5) 

But apparently Option is NOT Traversable.

3 Answers

There is nothing wrong with Vector(1, 2, 3) ++ Some(5).toSeq, this is how it is usually done.

While experimenting with the code to answer your question I have found that (surprisingly to me) you do not have to write toSeq even in Scala 2.10 - 2.12, thanks to option2Iterable defined in scala.Option companion object. This implicit conversion make sure Option can be used where Iterable is expected, which is enough for Vector.++ operator.

Following works: Vector(1, 2, 3) ++ Some(5)

You do not need to use toSeq even when concatenating multiple options, like Some(1) ++ Some(2) - the result is List(1, 2).

In Scala 2.13 Option is derived from IterableOnce, therefore even the implicit conversion is not necessary.

Option was made IterableOnce in Scala 2.13 by Make Option extend IterableOnce #8038

sealed abstract class Option[+A] extends IterableOnce[A] with Product with Serializable

so the following should work Scala 2.13

Vector(1, 2, 3) ++ Some(5)
Vector(1, 2, 3) ++ None
// res1: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3, 5)
// res2: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3)

I would pattern match it.

val v: Vector[Int] = optional match {
  case Some(x) => Vector(1, 2, 3) :+ x
  case None => Vector(1, 2, 3)
}
Related