4clojure:set-intersection,递归lambda

时间:2016-03-22 19:39:15

标签: clojure

我正在尝试编写一个递归的lambda函数(接受两个参数),它找到两个(可能)未排序的集合之间的交集。这是代码,我相信大多数人会直截了当地发现:

(fn intersection [a b]
(fn inner [x y out]
  (if (empty? x) out
  (if (nil? (some ((set (first x)) y )))
    (inner (rest x) y out))))
    (inner (rest x) y (cons (first x) out))
    (inner a b '[])
)

我希望使用这个lambda函数交集代替下面的下划线_:

(= (__ #{0 1 2 3} #{2 3 4 5}) #{2 3})

但是,这段代码无法编译,坚持认为Java是Unable to resolve symbol: inner in this context ...

有什么建议吗?

来源:http://www.4clojure.com/problem/81

1 个答案:

答案 0 :(得分:3)

你可以尝试:

#(set (filter %1 %2))

因为集合是函数(参见另一个有用的示例there)。 %1%2的语法与写作相同:

(fn [s1 s2] (set (filter s1 s2)))

或者更简洁:

(comp set filter)

关于inner错误,你只是错位了parens(但我真的没有看到逻辑):

(fn intersection [a b]
  (fn inner [x y out]
    (if (empty? x) out
        (if (nil? (some ((set (first x)) y )))
          (inner (rest x) y out)))
    (inner (rest x) y (cons (first x) out))
    (inner a b '[])))

如果你坚持手动构建套装(我很久以前就不会这样做了),你最终会得到类似的东西:

(fn [s1 s2]
  (reduce #(if (contains? s2 %2) (conj %1 %2) %1) #{} s1))

但真正的第一个解决方案是最优雅的。