在 clojure 中的两个集合之间实现 XOR

Sti*_*ode 1 recursion functional-programming clojure

我正在尝试学习 Clojure——而且我很环保。我正在尝试实现两个集合之间集差的递归版本。

我试图做的是首先组合两个列表,将组合转换为集合以删除重复项,然后将混乱传递回其自身并检查组合集合的第一个元素是否在两个输入列表中。如果它将合并集合的其余部分与原始集合一起传回并重复该过程......但它总是传回一个空列表。我不假设代码那么好。我是函数式编程的新手。

也许我没有正确使用逻辑?我做了一个测试,common-elms 开始时不是空的,但也许它会提前返回空列表?任何帮助将非常感激。谢谢。

(defn alone 
([l1 l2]
    (cond (empty? l1) l2
      (empty? l2) l1
      :else (alone (vec (set (into l1 l2))) '() l1 l2)))

([common-elms return-list l1 l2]
    "common-elms = set of common elements
     return-list = list of XOR items 
     l1 = list 1
     l2 = list 2 "
    (cond (empty? common-elms) return-list
          (and (contains? (first common-elms) l1) (contains? (first common-elms) l2))
            (alone (rest common-elms) return-list l1 l2)
          :else (alone (rest common-elms) return-list l1 l2))))
Run Code Online (Sandbox Code Playgroud)

Iva*_*rre 5

或者更简单,使用clojure.set命名空间:

(defn xor-list [l1 l2]
  (let [s1 (set l1)
        s2 (set l2)]
    (seq (clojure.set/difference 
           (clojure.set/union s1 s2) 
           (clojure.set/intersection s1 s2)))))
Run Code Online (Sandbox Code Playgroud)

但这只是返回列表的两个参数的函数。这应该在一般情况下得到增强,clojure.set/xor例如clojure.set/intersection任何数量的集合返回一个集合。