【问题标题】:Outer join in ClojureClojure 中的外部联接
【发布时间】:2012-10-12 04:11:37
【问题描述】:

类似这个问题: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值)的条目。

【问题讨论】:

    标签: clojure outer-join


    【解决方案1】:

    Sean Devlin(Full Disclojure 成名)table-utils 具有以下联接类型:

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

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

    • fn-tuple 替换为juxt
    • 将 ns 声明中的整个 (:use ) 子句替换为 (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))
    

    库的使用是join类型,两个集合(如上例的两组map,或者两个sql结果集)和至少一个join 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 在他的要点中有some examples

    【讨论】:

    • 虽然我最初不愿意复制和粘贴代码,但这是我最终解决问题的方法。谢谢!
    • 我也有同样的犹豫,但是有 SQL 背景,这些抽象自然而然,所以最后我屈服了。也许我会尝试自己写一个这样的库并推动它到 Clojars,但我对 github 和开源的东西不是很熟悉..
    • 我尝试使用 Clojure 1.6,在上述建议的修复之后,它适用于上面的示例,但是我有 2 个表的堆栈溢出错误,每个表大约有 4,000 行。这是错误:“java.lang.StackOverflowError:null”。我已经用 :jvm-opts ["-Xmx1024m"] 设置了我的项目,请提出任何简单的修复或替代方案。谢谢!
    • 源码中join-worker的实现中将“reduce concat”替换为“apply concat”可以解决栈溢出问题。
    猜你喜欢
    • 1970-01-01
    • 2011-12-22
    • 1970-01-01
    • 2017-08-04
    • 1970-01-01
    • 1970-01-01
    • 2013-07-06
    • 2018-04-12
    • 1970-01-01
    相关资源
    最近更新 更多