External join in Clojure

Similar to this question: Internal join in clojure

Is there a function for external joins (left, right, and full) that runs on map collections in any of the Clojure libraries?

I assume that this can be done by modifying the clojure.set/join code, but this seems to be a fairly common requirement, so check if it exists.

Something like that:

 (def s1 #{{:a 1, :b 2, :c 3} {:a 2, :b 2}}) (def s2 #{{:a 2, :b 3, :c 5} {:a 3, :b 8}}) ;=> (full-join s1 s2 {:a :a}) ; ; #{{:a 1, :b 2, :c 3} ; {:a 2, :b 3, :c 5} ; {:a 3, :b 8}} 

And the corresponding functions for the left and right outer join, i.e. including records that do not have a value (or nil ) for the join key on the left, right, or both sides.

+8
outer-join clojure
source share
1 answer

Sean Devlin ( glory of the full Disclojure table-utils has the following connection types:

  • intraparty join
  • left outer_connection
  • right outer_connection
  • full external_connection
  • naturally join
  • cross connect

It has not been updated after a while, but works in 1.3, 1.4, and 1.5. To make it work without any external dependencies:

  • replace fn-tuple with juxt
  • replace the whole sentence (:use ) in the ns declaration with (require [clojure.set :refer [intersection union]])
  • add the map-vals function below:

or

 (defn map-vals [f coll] (into {} (map (fn [[kv]] {k (fv)}) coll))) 

or for Clojure 1.5 and above

 (defn map-vals [f coll] (reduce-kv (fn [acc kv] (assoc acc k (fv))) {} coll)) 

Using a library is a connection type, two collections (two sets of maps, for example, the example above or two sql sets) and at least one fn union. Since keywords are functions on maps, usually only connection keys are enough:

 => (full-outer-join s1 s2 :a :a) ({:a 1, :c 3, :b 2} {:a 2, :c 5, :b 3} {:b 8, :a 3}) 

If I remember correctly, Sean tried to get cutlery in Contrib some time ago, but it didn’t work. It is a pity that he never had his own project (on github / clojars). From time to time, a question arises about a similar library in Stackoverflow or the Google Clojure group.

Another option would be to use the datalog library from datomic to query Clojure data structures. Stuart Halloway has a few examples in his own words.

+4
source share

All Articles