我如何计算 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 是一个了不起的开发工具。我喜欢集合操作库的想法。我早该猜到有这么回事
我需要一个包含两个列表的函数,例如(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 是一个了不起的开发工具。我喜欢集合操作库的想法。我早该猜到有这么回事