Return a set that is the first set without elements of the remaining sets
user=> (difference #{1 2 3}) #{1 2 3} user=> (difference #{1 2} #{2 3}) #{1} user=> (difference #{1 2 3} #{1} #{1 4} #{3}) #{2}
user=> (difference (set (keys {:1 1 :2 2 :3 3})) (set (keys {:1 1 :2 2}))) #{:3} user=> (difference (set (keys {:1 1 :2 2})) (set (keys {:1 1 :2 2 :3 3}))) #{}
;; Advice: Do not call difference with non-set arguments. If you are ;; concerned that you may be unintentionally doing so, and want an ;; exception to be thrown if you do, consider using the library ;; funjible (https://github.com/jafingerhut/funjible) which provides ;; its own definition of difference that is identical to Clojure's, ;; except it checks the types of its arguments. ;; difference might or might not return what you expect if you give it ;; values that are not sets. The implementation of difference _does not ;; check_ whether you are actually giving it values that are sets. It ;; _assumes_ so. ;; This looks like what someone might expect. It _happens_ to give ;; back the same answer as if you coerced the second argument to a ;; set. user=> (difference #{1 3 5} [1 2 3 4 5 6]) #{} ;; This is not the difference between the two collections (if they ;; were both sets) at all! user=> (difference #{1 3 5} [2 4 6 8 10 12]) #{} ;; Give it only sets, and it returns the correct answer. user=> (set/difference #{1 3 5} #{2 4 6 8 10 12}) #{1 3 5} ;; Also not the correct set difference, because the second arg is a ;; vector, not a set. user=> (difference #{-1 10 20 30} [-1 10 20 30 40]) #{20 -1 30 10} ;; This is correct. user=> (difference #{-1 10 20 30} #{-1 10 20 30 40}) #{} ;; Why not change the definition of difference so it throws an exception if ;; you give it a non-set argument? I would guess that the primary ;; reason is that the extra run-time type checks would slow difference down ;; by an amount that the Clojure core team does not want everyone to ;; have to pay on every such call. ;; Related Clojure tickets: ;; https://dev.clojure.org/jira/browse/CLJ-1953 ;; https://dev.clojure.org/jira/browse/CLJ-2287
;; difference subtracts the trailing sets (def s1 #{1 2}) (def s2 #{2 3}) (set/difference s1 s2) ;;=> #{1} ;; to get the exclusive union #{1 3} (or "XOR"): (set/difference (set/union s1 s2) (set/intersection s1 s2)) ;;=> #{1 3} ;; You can extend this to maps: (defn- map-xor [m1 m2] (map (juxt (fn [[k1 _] _] k1) (fn [[_ v1] [_ v2]] (set/difference (set/union (set v1) (set v2)) (set/intersection (set v1) (set v2))))) m1 m2)) (map-xor {:a [1 2] :b [2 3]} {:a [2 3] :b [3]}) ;;=> ([:a #{1 3}] [:b #{2}])
disj[oin]. Returns a new set of the same (hashed/sorted) type, that does not contain key(s).
difference