Scala Saturday – The Set.diff Method

Sometimes you have two sets of information, and you want to know what is in one set that the other set lacks. You want to perform a set difference operation.

What’s the Difference?

Given two sets, A and B, the difference between A and B—the items in A that are not in B—is written as follows:

A \ B

Likewise, the difference in B and A—the items in B that are not in A—is written vice versa:

B \ A

Set operations are frequently easiest to convey with a diagram:

An illustration of two sets, A and B, represented as two filled circles that are slightly overlapping. The difference (A \ B) is the part of set A not overlapping set B. The difference (B \ A) is the part of set B not overlapping set A.
The Difference in Two Sets A and B

It’s worth noting that a set difference operation is like arithmetic subtraction in that it matters which operand comes first. That is …

A \ B ≠ B \ A

White & nerdy mathematicians say that the set difference operation does not commute.

Always Never the Same

Continuing with my penchant for using band lineups as examples, put the original lineup of the band Kansas in one set and the current lineup in another:

val original = Set(
  "Walsh", "Livgren", "Williams",
  "Steinhardt", "Hope", "Ehart")
val current = Set(
  "Platt", "Manion", "Williams",
  "Ragsdale", "Greer", "Ehart")

To get the original members no longer with the band, use the Set.diff method to take the difference in the original lineup and the current:

val departed = original.diff(current)
// departed: scala.collection.immutable.Set[String] = 
//   Set(Walsh, Steinhardt, Livgren, Hope)

To get the current members who were not in the original lineup, do the opposite—take the difference in the current lineup and the original:

val noobs = current.diff(original)
// noobs: scala.collection.immutable.Set[String] = 
//   Set(Platt, Ragsdale, Manion, Greer)

How ’bout that! Simple enough, I suppose, but seeing as set difference is a whole lot like arithmetic subtraction, wouldn’t it be really nice if we could express our set difference operations just like we do arithmetic subtraction?

A − B

Good news: You can! Well, almost. Scala defines a -- operator so that we can more mathematical-looking code:

val departed = original -- current
val noobs = current -- original
// departed: scala.collection.immutable.Set[String] = 
//   Set(Walsh, Steinhardt, Livgren, Hope)
// noobs: scala.collection.immutable.Set[String] = 
//   Set(Platt, Ragsdale, Manion, Greer)

Incidentally, Scala does also define a minus operator, but it is for removing one item at a time, not a set of items. However, with it you can write code like this:

val noRhythm = current - "Ehart" - "Greer"
// noRhythm: scala.collection.immutable.Set[String] = 
//   Set(Platt, Ragsdale, Manion, Williams)

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.