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