Clojure如何从自定义集合中移除指定元素?
解决Clojure哈希集合的过滤问题
嘿,刚接触Clojure的话,这种持久化数据结构的操作确实需要一点点时间适应,我来帮你搞定这个问题~
你想要的效果其实可以通过remove函数结合简单的判断条件实现,核心就是检查集合a中每个条目的第一个元素是否存在于集合b中。直接看代码:
(def a #{[1 345] [2 346] [3 347]}) (def b #{1 2}) ;; 先得到过滤后的序列 (remove (fn [[x _]] (contains? b x)) a) ;; 转成哈希集合(如果你需要的话) (set (remove (fn [[x _]] (contains? b x)) a))
运行这段代码就能得到你预期的#{[3 347]}了。
为什么这个方法有效?
- 匿名函数
(fn [[x _]] (contains? b x))做了两件事:首先解构集合a里的每个向量条目,取出第一个元素x;然后用contains?检查x是否在集合b中(集合的contains?是O(1)操作,效率很高)。 remove函数会过滤掉所有让这个判断函数返回true的元素,留下的就是第一个元素不在b里的条目。
你之前尝试remove没成功,大概率是没写对判断条件——比如直接传集合b给remove是不行的,remove需要的是一个返回布尔值的判断函数,不是集合本身。另外把a转成map也没必要,因为这里的条目是向量,不是键值对映射,反而会绕弯路。
更简洁的写法
如果你喜欢Clojure的简洁语法,也可以用匿名函数的简写形式:
(set (remove #(contains? b (first %)) a))
这里#(...)是匿名函数的简写,(first %)就是取每个条目的第一个元素,和之前的解构写法效果完全一致,看你习惯哪种风格就好~
内容的提问来源于stack exchange,提问作者P696
相关产品推荐
相关产品推荐

