我如何计算 Clojure 中的列表交集?

How do I compute a list intersection in Clojure?

我需要一个包含两个列表的函数,例如(1 2 3 4) 和 (2 3 4 5),以及 returns 它们的交集,即 (2 3 4)。我写了一个有效的函数,但它有 8 行长,而且非常“不像 Clojurelike”,因为我对这项运动很陌生。我知道那里有一些优雅的东西,地狱,甚至可能是解决整个问题的 Clojure 关键字。 比较只需要在顶层进行,而不需要遍历整个列表结构。 提前谢谢你。

如果不介意结果集的顺序,集合操作有内置库

(require '[clojure.set :as set])
(set/intersection (set '(1 2 3 4) ) (set '( 3 4 5)))   ; ==> returns #{4 3}

除了上面的标准答案,如果出于某种原因你需要保留原来的顺序,你可以使用这样的技巧:

(ns tst.demo.core
  (:use tupelo.core tupelo.test))

(let [a       [1 2 3 4]
      b       [3 4 5]
      result  (filterv (set a) b) ]
  (is= result [3 4]))

基于我最喜欢的 template project. Please see also the list of documentation,尤其是 Clojure CheatSheet。

我一发布我的问题,就又试了一下,一天之内想出了这个:

(defmacro FindAtomInList [A L] `(first (drop-while #(not= ~A %) ~L)))   ;; If Atom A is in List L, return it, otherwise, nil.
(defn Intersect [L1 L2] (filter some? (map #(FindAtomInList % L1) L2))) ;; Return the intersection of Lists 1 and 2. Empty if none.

感谢您的帮助。 repl 是一个了不起的开发工具。我喜欢集合操作库的想法。我早该猜到有这么回事