Scala: How to append and prepend items to Vector and Seq

Scala FAQ: How do I append or prepend one or more elements to a Vector or Seq class?

Back to top

Solution

To append or prepend one or more elements to a Vector or Seq, use these methods:

  • to append one item, use :+
  • to append multiple items, use ++
  • to prepend one item, use +:
  • to prepend multiple items, use ++:

In tabular form that looks like this:

Need Method
append 1 item oldSeq :+ e
append multiple items oldSeq ++ newSeq
prepend 1 item e +: oldSeq
prepend multiple items newSeq ++: oldSeq

Remember that Vector and Seq are immutable, so you can’t modify them. Therefore, during the append or prepend operations, you need to assign the result to a new variable.

Back to top

Example data

In the examples that follow, I’ll always begin with this variable:

scala> val a = Vector(1, 2, 3)
a: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3)
Back to top

Append a single item

This is how you append a single item to a Vector:

scala> val b = a :+ 4
b: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3, 4)

Notice that it uses the :+ method.

Back to top

Append multiple elements

To append multiple elements to a Vector, use the ++ method:

scala> val b = a ++ Vector(4, 5)
b: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3, 4, 5)
Back to top

Prepend a single item

To prepend a single item to a Vector, use the +: method:

scala> val b = 0 +: a
b: scala.collection.immutable.Vector[Int] = Vector(0, 1, 2, 3)
Back to top

Prepend multiple elements

To prepend multiple elements to a Vector, use the ++: method:

scala> val b = Seq(-1, 0) ++: a
b: scala.collection.immutable.Vector[Int] = Vector(-1, 0, 1, 2, 3)
Back to top

Seq works just like Vector

Though I only showed a Seq in the last example, it uses the same append and prepend methods as the Scala Vector class.

Back to top

How to remember the method names

One way I remember the method names is to think that the : represents the side that the sequence is on, so when I use +:, I know that the sequence needs to be on the right, like this:

0 +: a

A more accurate way to think about the method names is that a Scala method name that ends with the : character is right-associative, meaning that the method comes from the variable on the right side of the expression. Therefore, in these examples, the methods actually come from the variable a on the far right side of the expression:

0 +: a
Seq(-1, 0) ++: a

In the other examples, the method comes from the variable a, which is on the left:

val b = a :+ 4
val b = a ++ Vector(4, 5)

Because you know that these methods come from the Vector and Seq classes, if you think about this associativity, you will always get the : character on the correct side.

(I don’t know why ++ is used in the last case. In the larger scheme, ++ is used consistently across the collections classes, but in this case it seems like creating a :++ method for immutable sequences would have made these examples more consistent.)

Back to top

A possible problem

Although I haven’t done this in production code, I just noticed that you can use the :+ and +: methods in a way that most likely won’t give you what you want:

// INTENTIONAL ERROR
scala> a :+ Seq(4,5)
res0: scala.collection.immutable.Vector[Any] = Vector(1, 2, 3, List(4, 5))
                                                      -------------------

// INTENTIONAL ERROR
scala> a +: Seq(4,5)
res1: Seq[Any] = List(Vector(1, 2, 3), 4, 5)
                      ---------------------

That usage might make sense with other sequential collections, but at the moment it looks like a potential cause of error. Because those methods treat the variable they’re appending/prepending as a single element, you end up with a sequence inside a sequence, which again is probably not what you want.

Back to top

Add new comment

Anonymous format

  • Allowed HTML tags: <em> <strong> <cite> <code> <ul type> <ol start type> <li> <pre>
  • Lines and paragraphs break automatically.