我在Clojure中有这样的变量测试:
( 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]对象,看起来像这样:
([: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中有一种简单的方法吗?
我看过这个帖子How can I remove an item from a sequence in Clojure?
并删除()但我仍然没有。那个帖子显示:
(remove #{:foo} #{:foo :bar}) ; => (:bar)
(remove #{:foo} [:foo :bar]) ; => (:bar)
(remove #{:foo} (list :foo :bar)) ; => (:bar)
但对我来说,我有更多的东西:
(remove #????? ([:foo :bar] [foo] [bar]))
我想最终得到([:foo:bar])。
答案 0 :(得分:2)
(remove pred)
(remove pred coll)
返回
coll
中(pred item)
返回false
的项目的延迟序列。
因此,您需要提供一个这样做的谓词,例如删除[circle]
:
#(= '[circle] %)
这是一个(匿名)函数,用于测试它的参数是否(值)等于向量[circle]
。
当然,您也可以将其概括为删除所有元素向量:
#(and (vector? %) (= 1 (.length %)))
或删除至少包含关键字的每个向量:
#(and (vector? %) (not-any? keyword? %))
我希望你能得到图片:)
答案 1 :(得分:0)
在这种情况下你可能需要这样的东西:
(remove (comp symbol? first) 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}])
因为要删除第一个值为symbol
的所有向量。
当然,如果你想删除所有只有一个符号值的向量,你应该更具体:
(remove #(and (vector? %)
(== 1 (count %))
(symbol? (first %)))
test)
您也可以反转您的逻辑,而不是删除不需要的数据,但需要保留所需的数据:
(filter (comp keyword? first) 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}])
答案 2 :(得分:0)
如果您想编写代码,就像您使用set
元素作为remove
(或其他一些函数)的谓词一样从线程提供的示例,您只需要把你想要摆脱的元素放在set
里面(正如你几乎所做的那样),但你需要知道需要引用的符号。
因此,在上一个示例中,第一个可能的错误原因是不引用向量列表:
(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
现在您还需要将#{}
内的符号引用为谓词:
(remove #{['foo] ['bar]} '([:foo :bar] [foo] [bar])) ;; => ([:foo :bar])
同样的规则也适用于您的第一个示例:
(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}])
将清理你的矢量列表。