Clojure Goodness: Getting Intersections Between Sets
In the clojure.set
namespace we can find the intersection
function. This functions accepts one or more sets as arguments and return a new set with all elements that are present in the sets that are passed as arguments to the intersection
function. The argument must be a set, so we need to convert other collection or seq values to a set first before we use it as an argument for the function.
In the following example we use one, two or three arguments for the intersection
function and also convert other types to a set to be used as argument:
(ns mrhaki.sample
(:require [clojure.set :refer [intersection]]
[clojure.test :refer [is]]))
;; Use intersection with sets to find common elements.
(is (= #{"Clojure"} (intersection #{"Java" "Scala" "Clojure"} #{"Clojure" "Groovy"})))
;; An empty set is returned if there is no common element.
(is (= #{} (intersection #{"Java" "Groovy" "Clojure"} #{"C++" "C#"})))
;; We can use more than two sets to find intersections.
(is (= #{"Clojure"} (intersection #{"Java" "Scala" "Clojure"}
#{"Clojure" "Groovy"}
#{"Groovy" "JRuby" "Clojure"})))
;; With one set intersections returns the set.
(is (= #{"Clojure" "Groovy"} (intersection #{"Clojure" "Groovy"})))
;; Only sets are allowed as arguments for the intersection function.
;; If one of the arguments is not a set the return value is unexpected.
(is (= #{} (intersection #{"Clojure" "Groovy"} ["Java" "Scala" "Clojure"])))
;; But we can convert a non-set to a set with the set function.
(is (= #{"Clojure"} (intersection #{"Clojure" "Groovy"} (set ["Java" "Scala" "Clojure"]))))
(is (= #{"Clojure"} (intersection #{"Clojure" "Groovy"} (set '("Java" "Scala" "Clojure")))))
;; Or using into #{}.
(is (= #{"Clojure"} (intersection #{"Clojure" "Groovy"}
(into #{} (vals {:platform "Java" :language "Clojure"})))))
Written with Clojure 1.10.1