10

类似于这个问题:Inner-join in clojure

是否有对任何 Clojure 库中的地图集合执行外连接(左、右和完整)的功能?

我想这可以通过修改代码来完成,clojure.set/join但这似乎是一个足够普遍的要求,所以值得检查它是否已经存在。

像这样的东西:

(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}}

nil以及左右外连接的相应功能,即包括左、右或两侧的连接键没有值(或值)的条目。

4

1 回答 1

5

Sean Devlin(以Full Disclojure闻名)的 table-utils具有以下连接类型:

  • 内部联接
  • 左外连接
  • 右外连接
  • 全外连接
  • 自然连接
  • 交叉连接

它已经有一段时间没有更新了,但可以在 1.3、1.4 和 1.5 中使用。要使其在没有任何外部依赖项的情况下工作:

  • 替换fn-tuplejuxt
  • (:use )将ns 声明中的整个子句替换为(require [clojure.set :refer [intersection union]])
  • 从下面添加函数 map-vals:

任何一个

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

或 Clojure 1.5 及更高版本

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

该库的用法是连接类型、两个集合(如上例的两组映射,或两个 sql 结果集)和至少一个连接 fn。由于关键字是地图上的函数,通常只有连接键就足够了:

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

如果我没记错的话,Sean 前段时间曾尝试将 table-utils 加入 contrib,但从未成功。太糟糕了,它从来没有拥有自己的项目(在 github/clojars 上)。Stackoverflow 或 Clojure Google 小组时不时会出现类似这样的库的问题。

另一种选择可能是使用来自 datomic 的数据日志库来查询 clojure 数据结构。Stuart Halloway 在他的要点中有一些 例子

于 2012-10-23T13:51:56.173 回答