Scala Vector class: method examples and syntax

This page contains a large collection of examples of how to use the Scala Vector class, including most of the methods that are available on a Vector. (Currently over 170 examples.)

Back to top

Introduction

Use the Vector class when you want to use a general-purpose, immutable indexed sequence in your Scala applications:

  • Immutable: the elements in the collection cannot be changed, and the collection cannot be resized
  • Indexed: you can access elements quickly by their element number, such as people(12345432) (a linked list would be very slow for this purpose)

Just as the ArrayBuffer is the recommended “go to” class for mutable indexed sequential collections, the Vector class is recommended as the general-purpose collections class for immutable indexed sequential collections.

Back to top

An important note about multithreaded applications

Under certain conditions the Vector is not safe to use in multithreaded applications. These notes come from the Vector class Scaladoc:

“Despite being an immutable collection, the implementation uses mutable state internally during construction. These state changes are invisible in single-threaded code but can lead to race conditions in some multi-threaded scenarios. The state of a new collection instance may not have been "published" (in the sense of the Java Memory Model specification), so that an unsynchronized non-volatile read from another thread may observe the object in an invalid state (see scala/bug#7838 for details).”

Back to top

An important note about the examples

Remember that Vector is immutable, so in all of the examples that follow you need to assign the result of the operation shown to a new variable, like this:

val x = nums.distinct
Back to top

Create a new Vector with initial elements

To create a new Vector with initial elements:

val nums = Vector(1, 2, 3)

val people = Vector(
    Person("Emily"),
    Person("Hannah"),
    Person("Mercedes")
)

When you need to be clear about what’s in the vector:

val x = Vector(1, 1.0, 1F)                   # Vector[Double] = Vector(1.0, 1.0, 1.0)
val x: Vector[Number] = Vector(1, 1.0, 1F)   # Vector[Number] = Vector(1, 1.0, 1.0)

trait Animal
case class Dog(name: String) extends Animal
case class Cat(name: String) extends Animal
val animalHouse: Vector[Animal] = Vector(    # Vector[Animal] = Vector(Dog(Rover), Cat(Felix))
    Dog("Rover"),
    Cat("Felix")
)

If you ever need to create an empty vector:

val nums = Vector[Int]()

Remember the constructor syntax is just syntactic sugar for apply:

val nums = Vector(1, 2, 3)                   # Vector(1, 2, 3)
val nums = Vector.apply(1, 2, 3)             # Vector(1, 2, 3)
Back to top

Create a new Vector by populating it

You can also create a new Vector that’s populated with initial elements using a Range:

# to, until
(1 to 5).toVector                   # Vector(1, 2, 3, 4, 5)
(1 until 5).toVector                # Vector(1, 2, 3, 4)

(1 to 10 by 2).toVector             # Vector(1, 3, 5, 7, 9)
(1 until 10 by 2).toVector          # Vector(1, 3, 5, 7, 9)
(1 to 10).by(2).toVector            # Vector(1, 3, 5, 7, 9)

('d' to 'h').toVector               # Vector(d, e, f, g, h)
('d' until 'h').toVector            # Vector(d, e, f, g)

('a' to 'f').by(2).toVector         # Vector(a, c, e)

# range method
Vector.range(1, 3)                  # Vector(1, 2)
Vector.range(1, 6, 2)               # Vector(1, 3, 5)

You can also use the fill and tabulate methods:

Vector.fill(3)("foo")               # Vector(foo, foo, foo)
Vector.tabulate(3)(n => n * n)      # Vector(0, 1, 4)
Vector.tabulate(4)(n => n * n)      # Vector(0, 1, 4, 9)

... this post is sponsored by my books ...
 

Back to top

How to add (append and prepend) elements to a Vector

Because Vector is immutable, you can’t add elements to an existing Vector. The way you work with Vector is to modify the elements it contains as you assign the results to a new Vector.

Method Description Example
:+ append 1 item oldSeq :+ e
++ append N items oldSeq ++ newSeq
+: prepend 1 item e +: oldSeq
++: prepend N items newSeq ++: oldSeq

Append and prepend examples

These examples show how to use the append and prepend methods:

val v1 = Vector(4,5,6)           # Vector(4, 5, 6)
val v2 = v1 :+ 7                 # Vector(4, 5, 6, 7)
val v3 = v2 ++ Seq(8,9)          # Vector(4, 5, 6, 7, 8, 9)

val v4 = 3 +: v3                 # Vector(3, 4, 5, 6, 7, 8, 9)
val v5 = Seq(1,2) ++: v4         # Vector(1, 2, 3, 4, 5, 6, 7, 8, 9)

About the : character in the method names

Note that during these operations the : character is always next to the old (original) sequence. I use that as a way to remember these methods.

The correct technical way to think about this 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, with +: and ++:, these methods comes from the Vector that’s on the right of the method name.

Back to top

Filtering methods (how to “remove” elements from an Vector)

A Vector is an immutable sequence, so you don’t remove elements from a Vector. Instead, you describe how to remove elements as you assign the results to a new collection. These methods let you “remove” elements during this process:

Method Description
distinct Return a new sequence with no duplicate elements
drop(n) Return all elements after the first n elements
dropRight(n) Return all elements except the last n elements
dropWhile(p) Drop the first sequence of elements that matches the predicate p
filter(p) Return all elements that match the predicate p
filterNot(p) Return all elements that do not match the predicate p
find(p) Return the first element that matches the predicate p
head Return the first element; can throw an exception if the Vector is empty
headOption Returns the first element as an Option
init All elements except the last one
intersect(s) Return the intersection of the vector and another sequence s
last The last element; can throw an exception if the Vector is empty
lastOption The last element as an Option
slice(f,u) A sequence of elements from index f (from) to index u (until)
tail All elements after the first element
take(n) The first n elements
takeRight(n) The last n elements
takeWhile(p) The first subset of elements that matches the predicate p

Examples

val a = Vector(10, 20, 30, 40, 10)    # Vector(10, 20, 30, 40, 10)
a.distinct                            # Vector(10, 20, 30, 40)
a.drop(2)                             # Vector(30, 40, 10)
a.dropRight(2)                        # Vector(10, 20, 30)
a.dropWhile(_ < 25)                   # Vector(30, 40, 10)
a.filter(_ < 25)                      # Vector(10, 20, 10)
a.filter(_ > 100)                     # Vector()
a.filterNot(_ < 25)                   # Vector(30, 40)
a.find(_ > 20)                        # Some(30)
a.head                                # 10
a.headOption                          # Some(10)
a.init                                # Vector(10, 20, 30, 40)
a.intersect(Seq(19,20,21))            # Vector(20)
a.last                                # 10
a.lastOption                          # Some(10)
a.slice(2,4)                          # Vector(30, 40)
a.tail                                # Vector(20, 30, 40, 10)
a.take(3)                             # Vector(10, 20, 30)
a.takeRight(2)                        # Vector(40, 10)
a.takeWhile(_ < 30)                   # Vector(10, 20)

As noted, head and last can throw exceptions:

scala> val a = Vector[Int]()
a: scala.collection.immutable.Vector[Int] = Vector()

scala> a.head
java.lang.UnsupportedOperationException: empty.head
  at scala.collection.immutable.Vector.head(Vector.scala:185)
  ... 28 elided

scala> a.last
java.lang.UnsupportedOperationException: empty.last
  at scala.collection.immutable.Vector.last(Vector.scala:197)
  ... 28 elided
Back to top

How to “update” Vector elements

Because Vector is immutable, you can’t update elements in place, but depending on your definition of “update,” there are a variety of methods that let you update a Vector as you assign the result to a new variable:

Method Returns
collect(pf) A new collection by applying the partial function pf to all elements of the vector, returning elements for which the function is defined
distinct A new sequence with no duplicate elements
flatten Transforms a list of lists into a single list
flatMap(f) When working with sequences, it works like map followed by flatten
map(f) Return a new sequence by applying the function f to each element in the Vector
updated(i,v) A new vector with the element at index i replaced with the new value v
union(s) A new vector that contains elements from the current vector and the sequence s
val x = Vector(Some(1), None, Some(3), None)
x.collect{case Some(i) => i}          # Vector(1, 3)

val x = Vector(1,2,1,2)
x.distinct                            # Vector(1, 2)
x.map(_ * 2)                          # Vector(2, 4, 2, 4)
x.updated(0,100)                      # Vector(100, 2, 1, 2)

val a = Vector(Seq(1,2), Seq(3,4))
a.flatten                             # Vector(1, 2, 3, 4)

val fruits = Vector("apple", "pear")
fruits.map(_.toUpperCase)             # Vector(APPLE, PEAR)
fruits.flatMap(_.toUpperCase)         # Vector(A, P, P, L, E, P, E, A, R)

Vector(2,4).union(Vector(1,3))        # Vector(2, 4, 1, 3)
Back to top

Transformer methods

A transformer method is a method that constructs a new collection from an existing collection.

Method Returns
collect(pf) Creates a new collection by applying the partial function pf to all elements of the vector, returning elements for which the function is defined
diff(c) The difference between this vector and the collection c
distinct A new sequence with no duplicate elements
flatten Transforms a list of lists into a single list
flatMap(f) When working with sequences, it works like map followed by flatten
map(f) A new sequence by applying the function f to each element in the Vector
reverse A new sequence with the elements in reverse order
sortWith(f) A new sequence with the elements sorted with the use of the function f
updated(i,v) A new Vector with the element at index i replaced with the new value v
union(c) A new sequence that contains all elements of the vector and the collection c
zip(c) A collection of pairs by matching the vector with the elements of the collection c
zipWithIndex A vector of each element contained in a tuple along with its index
val x = Vector(Some(1), None, Some(3), None)
x.collect{case Some(i) => i}          # Vector(1, 3)

# diff
val oneToFive = (1 to 5).toVector     # val oneToFive = (1 to 5).toVector
val threeToSeven = (3 to 7).toVector  # Vector(3, 4, 5, 6, 7)
oneToFive.diff(threeToSeven)          # Vector(1, 2)
threeToSeven.diff(oneToFive)          # Vector(6, 7)

Vector(1,2,1,2).distinct              # Vector(1, 2)

val a = Vector(Seq(1,2), Seq(3,4))
a.flatten                             # Vector(1, 2, 3, 4)

# map, flatMap
val fruits = Vector("apple", "pear")
fruits.map(_.toUpperCase)             # Vector(APPLE, PEAR)
fruits.flatMap(_.toUpperCase)         # Vector(A, P, P, L, E, P, E, A, R)

Vector(1,2,3).reverse                 # Vector(3, 2, 1)

val nums = Vector(10, 5, 8, 1, 7)
nums.sorted                           # Vector(1, 5, 7, 8, 10)
nums.sortWith(_ < _)                  # Vector(1, 5, 7, 8, 10)
nums.sortWith(_ > _)                  # Vector(10, 8, 7, 5, 1)

Vector(1,2,3).updated(0,10)           # Vector(10, 2, 3)
Vector(2,4).union(Vector(1,3))        # Vector(2, 4, 1, 3)

# zip
val women = Vector("Wilma", "Betty")  # Vector(Wilma, Betty)
val men = Vector("Fred", "Barney")    # Vector(Fred, Barney)
val couples = women.zip(men)          # Vector((Wilma,Fred), (Betty,Barney))

val a = Vector.range('a', 'e')        # Vector(a, b, c, d)
a.zipWithIndex                        # Vector((a,0), (b,1), (c,2), (d,3))
Back to top

Informational and mathematical methods

These methods let you obtain information from a collection.

Method Returns
contains(e) True if the vector contains the element e
containsSlice(s) True if the vector contains the sequence s
count(p) The number of elements in the vector for which the predicate is true
endsWith(s) True if the vector ends with the sequence s
exists(p) True if the predicate returns true for at least one element in the vector
find(p) The first element that matches the predicate p, returned as an Option
forall(p) True if the predicate p is true for all elements in the vector
hasDefiniteSize True if the vector has a finite size
indexOf(e) The index of the first occurrence of the element e in the vector
indexOf(e,i) The index of the first occurrence of the element e in the vector, searching only from the value of the start index i
indexOfSlice(s) The index of the first occurrence of the sequence s in the vector
indexOfSlice(s,i) The index of the first occurrence of the sequence s in the vector, searching only from the value of the start index i
indexWhere(p) The index of the first element where the predicate p returns true
indexWhere(p,i) The index of the first element where the predicate p returns true, searching only from the value of the start index i
isDefinedAt(i) True if the vector contains the index i
isEmpty True if the vector contains no elements
lastIndexOf(e) The index of the last occurrence of the element e in the vector
lastIndexOf(e,i) The index of the last occurrence of the element e in the vector, occurring before or at the index i
lastIndexOfSlice(s) The index of the last occurrence of the sequence s in the vector
lastIndexOfSlice(s,i) The index of the last occurrence of the sequence s in the vector, occurring before or at the index i
lastIndexWhere(p) The index of the first element where the predicate p returns true
lastIndexWhere(p,i) The index of the first element where the predicate p returns true, occurring before or at the index i
max The largest element in the vector
min The smallest element in the vector
nonEmpty True if the vector is not empty (i.e., if it contains 1 or more elements)
product The result of multiplying the elements in the collection
segmentLength(p,i) The length of the longest segment for which the predicate p is true, starting at the index i
size The number of elements in the vector
startsWith(s) True if the vector begins with the elements in the sequence s
startsWith(s,i) True if the vector has the sequence s starting at the index i
sum The sum of the elements in the vector
fold(s)(o) “Fold” the elements of the vector using the binary operator o, using an initial seed s (see also reduce)
foldLeft(s)(o) “Fold” the elements of the vector using the binary operator o, using an initial seed s, going from left to right (see also reduceLeft)
foldRight(s)(o) “Fold” the elements of the vector using the binary operator o, using an initial seed s, going from right to left (see also reduceRight)
reduce “Reduce” the elements of the vector using the binary operator o
reduceLeft “Reduce” the elements of the vector using the binary operator o, going from left to right
reduceRight “Reduce” the elements of the vector using the binary operator o, going from right to left

Examples

First, some sample data:

val evens = Vector(2, 4, 6)
val odds = Vector(1, 3, 5)
val fbb = "foo bar baz"
val firstTen = (1 to 10).toVector          # Vector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val fiveToFifteen = (5 to 15).toVector     # Vector(5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
val empty = Vector[Int]()                  # Vector[Int] = Vector()
val letters = ('a' to 'f').toVector        # Vector(a, b, c, d, e, f)

The examples:

evens.contains(2)                          # true
firstTen.containsSlice(Seq(3,4,5))         # true
firstTen.count(_ % 2 == 0)                 # 5
firstTen.endsWith(Seq(9,10))               # true
firstTen.exists(_ > 10)                    # false
firstTen.find(_ > 2)                       # Some(3)
firstTen.forall(_ < 20)                    # true
firstTen.hasDefiniteSize                   # true
empty.hasDefiniteSize                      # true
letters.indexOf('b')                       # 1 (zero-based)
letters.indexOf('d', 2)                    # 3
letters.indexOf('d', 3)                    # 3
letters.indexOf('d', 4)                    # -1
letters.indexOfSlice(Seq('c','d'))         # 2
letters.indexOfSlice(Seq('c','d'),2)       # 2
letters.indexOfSlice(Seq('c','d'),3)       # -1
firstTen.indexWhere(_ == 3)                # 2
firstTen.indexWhere(_ == 3, 2)             # 2
firstTen.indexWhere(_ == 3, 5)             # -1
letters.isDefinedAt(1)                     # true
letters.isDefinedAt(20)                    # false
letters.isEmpty                            # false
empty.isEmpty                              # true

# lastIndex...
val fbb = "foo bar baz"
fbb.indexOf('a')                           # 5
fbb.lastIndexOf('a')                       # 9
fbb.lastIndexOf('a', 10)                   # 9
fbb.lastIndexOf('a', 9)                    # 9
fbb.lastIndexOf('a', 6)                    # 5
fbb.lastIndexOf('a', 5)                    # 5
fbb.lastIndexOf('a', 4)                    # -1

fbb.lastIndexOfSlice("ar")                 # 5
fbb.lastIndexOfSlice(Seq('a','r'))         # 5
fbb.lastIndexOfSlice(Seq('a','r'), 4)      # -1
fbb.lastIndexOfSlice(Seq('a','r'), 5)      # 5
fbb.lastIndexOfSlice(Seq('a','r'), 6)      # 5

fbb.lastIndexWhere(_ == 'a')               # 9
fbb.lastIndexWhere(_ == 'a', 4)            # -1
fbb.lastIndexWhere(_ == 'a', 5)            # 5
fbb.lastIndexWhere(_ == 'a', 6)            # 5
fbb.lastIndexWhere(_ == 'a', 8)            # 5
fbb.lastIndexWhere(_ == 'a', 9)            # 9

firstTen.max                               # 10
letters.max                                # f
firstTen.min                               # 1
letters.min                                # a
letters.nonEmpty                           # true
empty.nonEmpty                             # false
firstTen.product                           # 3628800
letters.size                               # 6

val x = Vector(1,2,9,1,1,1,1,4)
x.segmentLength(_ < 4, 0)                  # 2
x.segmentLength(_ < 4, 2)                  # 0
x.segmentLength(_ < 4, 3)                  # 4
x.segmentLength(_ < 4, 4)                  # 3

firstTen.startsWith(Seq(1,2))              # true
firstTen.startsWith(Seq(1,2), 0)           # true
firstTen.startsWith(Seq(1,2), 1)           # false
firstTen.sum                               # 55

firstTen.fold(100)(_ + _)                  # 155
firstTen.foldLeft(100)(_ + _)              # 155
firstTen.foldRight(100)(_ + _)             # 155
firstTen.reduce(_ + _)                     # 55
firstTen.reduceLeft(_ + _)                 # 55
firstTen.reduceRight(_ + _)                # 55

firstTen.fold(100)(_ - _)                  # 45
firstTen.foldLeft(100)(_ - _)              # 45
firstTen.foldRight(100)(_ - _)             # 95
firstTen.reduce(_ - _)                     # -53
firstTen.reduceLeft(_ - _)                 # -53
firstTen.reduceRight(_ - _)                # -5

More on fold and reduce

Back to top

Grouping methods

These methods generally let you create multiple groups from a collection.

Method Returns
groupBy(f) A map of collections created by the function f
grouped Breaks the vector into fixed-size iterable collections
partition(p) Two collections created by the predicate p
sliding(i,s) Group elements into fixed size blocks by passing a sliding window of size i and step s over them
span(p) A collection of two collections; the first created by vector.takeWhile(p), and the second created by vector.dropWhile(p)
splitAt(i) A collection of two collections by splitting the vector at index i
unzip The opposite of zip, breaks a collection into two collections by dividing each element into two pieces; such as breaking up a vector of Tuple2 elements

Examples

val firstTen = (1 to 10).toVector      # Vector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

firstTen.groupBy(_ > 5)                # Map(false -> Vector(1, 2, 3, 4, 5), true -> Vector(6, 7, 8, 9, 10))
firstTen.grouped(2)                    # Iterator[Vector[Int]] = non-empty iterator
firstTen.grouped(2).toVector           # Vector(Vector(1, 2), Vector(3, 4), Vector(5, 6), Vector(7, 8), Vector(9, 10))
firstTen.grouped(5).toVector           # Vector(Vector(1, 2, 3, 4, 5), Vector(6, 7, 8, 9, 10))

"foo bar baz".partition(_ < 'c')       # (" ba ba", foorz)  // a Tuple2
firstTen.partition(_ > 5)              # (Vector(6, 7, 8, 9, 10), Vector(1, 2, 3, 4, 5))

firstTen.sliding(2)                    # Iterator[Vector[Int]] = non-empty iterator
firstTen.sliding(2).toVector           # Vector(Vector(1, 2), Vector(2, 3), Vector(3, 4), Vector(4, 5), Vector(5, 6), Vector(6, 7), Vector(7, 8), Vector(8, 9), Vector(9, 10))  
firstTen.sliding(2,2).toVector         # Vector(Vector(1, 2), Vector(3, 4), Vector(5, 6), Vector(7, 8), Vector(9, 10))  
firstTen.sliding(2,3).toVector         # Vector(Vector(1, 2), Vector(4, 5), Vector(7, 8), Vector(10))
firstTen.sliding(2,4).toVector         # Vector(Vector(1, 2), Vector(5, 6), Vector(9, 10)) 

val x = Vector(15, 10, 5, 8, 20, 12)
x.groupBy(_ > 10)                      # Map(false -> Vector(10, 5, 8), true -> Vector(15, 20, 12))
x.partition(_ > 10)                    # (Vector(15, 20, 12), Vector(10, 5, 8))
x.span(_ < 20)                         # (Vector(15, 10, 5, 8), Vector(20, 12))
x.splitAt(2)                           # (Vector(15, 10), Vector(5, 8, 20, 12))

More information:

Back to top

Looping over a Vector with for and foreach

These examples show how to loop/iterate over a vector with for and foreach. (As I write in Functional Programming, Simplified, foreach is only used for side effects, and therefore I rarely use it.)

val oneToFive = Vector(1, 2, 3, 4, 5)

for (i <- oneToFive) yield i           # Vector(1, 2, 3, 4, 5)
for (i <- oneToFive) yield i * 2       # Vector(2, 4, 6, 8, 10)
for (i <- oneToFive) yield i % 2       # Vector(1, 0, 1, 0, 1)

for {                                  # Vector(3, 4, 5)
    i <- oneToFive
    if i > 2
} yield i

for {                                  # Vector(6, 8, 10)
    i <- oneToFive
    if i > 2
} yield {
    // could be multiple lines here
    i * 2
}

# foreach (which i rarely use)
val oneToThree = Vector(1, 2, 3)
oneToThree.foreach(print)              # 123
for (i <- oneToThree) print(i)         # 123
Back to top

A few things you can do with a Vector of Options

The Option type is used a lot in idiomatic Scala code, so here are some ways to work with a Vector that contains Options.

val x = Vector(Some(1), None, Some(3), None)

x.flatten                              # Vector(1, 3)
x.collect{case Some(i) => i}           # Vector(1, 3)


# map, flatten, flatMap
import scala.util.Try
def toInt(s: String): Option[Int] = Try(Integer.parseInt(s)).toOption
val strings = Vector("1", "2", "foo", "3", "bar")

strings.map(toInt)                     # Vector(Some(1), Some(2), None, Some(3), None)
strings.map(toInt).flatten             # Vector(1, 2, 3)
strings.flatMap(toInt)                 # Vector(1, 2, 3)
Back to top

Scala Vector summary

I hope these Vector examples are helpful. Most of these examples will work very similarly with other immutable sequential collections classes like Seq, IndexedSeq, LinearSeq, List, and more. (Eventually I’ll create dedicated pages for each of those types, and others, such as ArrayBuffer and ListBuffer.)

As a final note, if I made a mistake, or you know another way to do something with an Vector I haven’t shown, leave a note in the Comments section.

Back to top

The Scala Cookbook

This tutorial is sponsored by the Scala Cookbook, which I wrote for O’Reilly, and which you can find on Amazon.com:

I hope it has been helpful. All the best, Al.

Back to top