How to get the (distinct) difference between two lists
From time to time I’ll see a post on JavaScript and take some time to work it out in ClojureScript. This helps me in a few ways:
- I get more practice in cljs
- I validate (or invalidate) my love for cljs
- I get more insight into how to sell cljs :)
I recently ran across Derick Bailey’s site and decided to rework some of his posts in cljs. The first post walks through getting the difference between two arrays, as a distinct list. The requirements are:
- We have a full list of valid values.
- We’re given a non-distinct list of both valid and invalid values.
- Find a distinct list containing only the valid values.
Derick’s thought process comes to “I wish I had a Set and a simple way to get the difference between two lists.” Well, that’s pretty nice because we have exactly that with cljs.
Sets
set
s are basically a “bag of values, where each value only appears once”. The “bag” part is important; it basically means there is no defined order to sets.
Solution
So let’s define our values as:
Finding our distinct values are simple one-liners thanks to cljs.core:
Selecting only the given valid values? We want the values that ONLY occur in both sets, also know as the intersection
:
As a bonus, what if we wanted all of the invalid values? Then, we want the valid values removed from the given-values:
Working through this post is a good reminder to continually work on expanding your knowledge of core functions. It’s not necessary to have every fn and it’s docs memorized, but it’s very handy to face a problem and have a good feel for what’s already provided.
Additional Notes
If you want order with sets, simply turn it into a seq
first. Calling seq
on the same set
will always give the same order:
The lib is clojure.set
in both cljs and clj. I believe this was a lib that was ported to cljs early and the naming hadn’t been decided on yet. Most cljs libs are cljs.lib
, but some clojure.lib
are still around (e.g. clojure.string
).