2

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.

Niko
  • 616
  • 4
  • 20

3 Answers3

5

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.

Suma
  • 33,181
  • 16
  • 123
  • 191
3

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)
Mario Galic
  • 47,285
  • 6
  • 56
  • 98
2

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)
}