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
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:
let original = set ["Walsh"; "Livgren"; "Williams"; "Steinhardt"; "Hope"; "Ehart"] let current = set ["Platt"; "Manion"; "Williams"; "Ragsdale"; "Greer"; "Ehart"]
To get the original members no longer with the band, use the Set.difference function to take the difference in the original lineup and the current:
let departed = Set.difference original current // val departed : Set<string> = // set ["Hope"; "Livgren"; "Steinhardt"; "Walsh"]
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:
let noobs = Set.difference current original // val noobs : Set<string> = // set ["Greer"; "Manion"; "Platt"; "Ragsdale"]
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! F# defines a minus operator so that we can do exactly that:
let departed = original - current let noobs = current - original // val departed : Set<string> = // set ["Hope"; "Livgren"; "Steinhardt"; "Walsh"] // val noobs : Set<string> = // set ["Greer"; "Manion"; "Platt"; "Ragsdale"]
3 replies on “F# Friday – The Set.difference Function”
[…] F# Friday – The Set.difference Function – Brad Collins […]
Also, as of F# 4.0, there are now Seq.except, List.except and Array.except, which do the same things on their respective collections.
Oh, I see. I haven’t taken a comprehensive look at the v4.0 API changes. Thanks for the tip, Mr. McDonald!
Interesting: I just took a look at the MSDN page on the List module, and it does not have
List.except
listed. But the F# REPL in VS 2015 likes it just fine.