How do I remove certain vector objects from a list in Clojure?
我在Clojure中有这样的变量测试:
1 | ( def test '([:circle {:cx 428, :cy 245, :r 32.2490309931942, :fill red}] [circle] [:line {:x1 461, :y1 222, :x2 365, :y2 163}] [:line {:x1 407, :y1 102, :x2 377, :y2 211}] [line])) |
我想从中删除[line]和[circle]对象,并使它看起来像这样:
1 | ([:circle {:cx 428, :cy 245, :r 32.2490309931942, :fill red}] [:line {:x1 461, :y1 222, :x2 365, :y2 163}] [:line {:x1 407, :y1 102, :x2 377, :y2 211}] ) |
在Clojure中有一种简单的方法吗?
我已经查看了此线程如何在Clojure中从序列中删除项目?
和remove(),但我仍然没有。该线程显示:
1 2 3 | (remove #{:foo} #{:foo :bar}) ; => (:bar) (remove #{:foo} [:foo :bar]) ; => (:bar) (remove #{:foo} (list :foo :bar)) ; => (:bar) |
但对我来说,我更喜欢:
1 | (remove #????? ([:foo :bar] [foo] [bar])) |
,我只想以([:: foo:bar])结尾。
摘录自
(remove pred) (remove pred coll) Returns a lazy sequence of the items in
coll for which(pred item) returnsfalse .
因此,您需要提供一个这样做的谓词,例如删除
1 | #(= '[circle] %) |
这是一个(匿名)函数,用于测试其参数是否等于向量
您当然也可以对此进行概括以删除所有一个元素向量:
1 | #(and (vector? %) (= 1 (.length %))) |
或删除每个包含至少一个关键字的向量:
1 | #(and (vector? %) (not-any? keyword? %)) |
我希望你能得到照片:)
如果您想像使用线程的
因此,在上一个示例中,第一个可能的错误原因是没有引用向量列表:
1 2 3 | (remove #????? ([:foo :bar] [foo] [bar])) ;; this list can not be evaluated and ;; will cause an error (remove #????? '([:foo :bar] [foo] [bar])) ;; make it a varied list by quoting it |
现在您还需要引用
1 | (remove #{['foo] ['bar]} '([:foo :bar] [foo] [bar])) ;; => ([:foo :bar]) |
相同的规则也适用于您的第一个示例:
1 2 3 4 | (remove #{['line] ['circle]} test) ;;=> ([:circle {:cx 428, :cy 245, :r 32.2490309931942, :fill red}] ;; [:line {:x1 461, :y1 222, :x2 365, :y2 163}] ;; [:line {:x1 407, :y1 102, :x2 377, :y2 211}]) |
将清理您的载体列表。
在这种情况下,您可能需要这样的东西:
1 | (remove (comp symbol? first) test) |
输出:
1 2 3 | ([:circle {:cx 428, :cy 245, :r 32.2490309931942, :fill red}] [:line {:x1 461, :y1 222, :x2 365, :y2 163}] [:line {:x1 407, :y1 102, :x2 377, :y2 211}]) |
要删除所有第一个值为
当然,如果要删除所有带有唯一值(即符号)的向量,则应更具体:
1 2 3 4 | (remove #(and (vector? %) (== 1 (count %)) (symbol? (first %))) test) |
您还可以反转逻辑,而不是删除不需要的数据,而是保留所需的数据:
1 | (filter (comp keyword? first) test) |
输出:
1 2 3 | ([:circle {:cx 428, :cy 245, :r 32.2490309931942, :fill red}] [:line {:x1 461, :y1 222, :x2 365, :y2 163}] [:line {:x1 407, :y1 102, :x2 377, :y2 211}]) |