How to delete elements from a List (or ListBuffer) in Scala

This is an excerpt from the 1st Edition of the Scala Cookbook (#ad) (partially modified for the internet). This is Recipe 11.4, “How to Delete Elements from a List (or `ListBuffer`) in Scala

Problem

You want to delete elements from a Scala List or ListBuffer.

Solution

A List is immutable, so you can’t delete elements from it, but you can filter out the elements you don’t want while you assign the result to a new variable:

scala> val originalList = List(5, 1, 4, 3, 2)
originalList: List[Int] = List(5, 1, 4, 3, 2)

scala> val newList = originalList.filter(_ > 2)
newList: List[Int] = List(5, 4, 3)

Rather than continually assigning the result of operations like this to a new variable, you can declare your variable as a var and reassign the result of the operation back to itself:

scala> var x = List(5, 1, 4, 3, 2)
x: List[Int] = List(5, 1, 4, 3, 2)

scala> x = x.filter(_ > 2)
x: List[Int] = List(5, 4, 3)

See Chapter 10 for other ways to get subsets of a collection using methods like filter, partition, splitAt, take, and more.

ListBuffer

If you’re going to be modifying a list frequently, it may be better to use a ListBuffer instead of a List. A ListBuffer is mutable, so you can remove items from it using all the methods for mutable sequences shown in Chapter 10. For example, assuming you’ve created a ListBuffer like this:

import scala.collection.mutable.ListBuffer
val x = ListBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9)

You can delete one element at a time, by value:

scala> x -= 5
res0: x.type = ListBuffer(1, 2, 3, 4, 6, 7, 8, 9)

You can delete two or more elements at once:

scala> x -= (2, 3)
res1: x.type = ListBuffer(1, 4, 6, 7, 8, 9)

That method looks like it takes a tuple, but it’s actually defined to take two parameters and a third varargs field.

You can delete elements by position:

scala> x.remove(0)
res2: Int = 1

scala> x
res3: scala.collection.mutable.ListBuffer[Int] = ListBuffer(4, 6, 7, 8, 9)

You can use remove to delete from a given starting position and provide the number of elements to delete:

scala> x.remove(1, 3)

scala> x
res4: scala.collection.mutable.ListBuffer[Int] = ListBuffer(4, 9)

You can also use --= to delete multiple elements that are specified in another collection:

scala> val x = ListBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9)
x: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9)

scala> x --= Seq(1,2,3)
res0: x.type = ListBuffer(4, 5, 6, 7, 8, 9)

Discussion

When you first start using Scala, the wealth of methods whose names are only symbols (+:, /:, :::, etc.) can seem daunting, but the -= and --= methods are used consistently across mutable collections, so it quickly becomes second nature to use them.

See Also

  • Recipes 10.17 through 10.19 show many ways to filter collections (filtering is a way of deleting)
  • Recipe 10.3, “Choosing a Collection Method to Solve a Problem”