类似的东西:
(or->
"foobar"
(clojure.string/starts-with? "foo")
(clojure.string/starts-with? "bar"))
=> true
如果没有,用多个or / and进行测试的惯用方式是什么?
答案 0 :(得分:9)
我在这里使用some
。本质上,这是一个顺序友好的or
检查,当所有条件基本相同时,可以帮助减少重复:
(some #(clojure.string/starts-with? "foobar" %)
["foo" "bar"])
它使用早期回报。
与and
等效的some
为every?
:
(every? odd? [3 5 9])
=> true
答案 1 :(得分:3)
我们需要在所有连续子句中对其进行插入之前将第一个参数插入。因此,解决方案必须是宏。如果我们准备不进行语法检查,则可以非常简洁地定义它:
(defmacro or-> [arg & pred-exprs]
(let [insert-expr (fn [[x & xs]] (list* x arg xs))
inserted-exprs (map insert-expr pred-exprs)]
(cons 'or inserted-exprs)))
有效:
problem=> (or-> "foobar"
(clojure.string/starts-with? "foo")
(clojure.string/starts-with? "bar"))
true
problem=> (or-> "foobar"
(clojure.string/starts-with? "for")
(clojure.string/starts-with? "bar"))
false
但是它为尝试的每个子句评估arg
格式。要只评估一次arg
形式,我们为let
插入gensym
形式:
(defmacro or-> [arg & pred-exprs]
(let [arg-sym (gensym)
insert-arg (fn [[x & xs]] (list* x arg-sym xs))
inserted-exprs (map insert-arg pred-exprs)]
`(let [~arg-sym ~arg] (or ~@inserted-exprs))))
我想用auto-gensym做到这一点,但是我想出了办法。但是,这样做并不是正常的Clojure意义上的线程化,而是始终执行所有线程化子句。
答案 2 :(得分:2)
通常,您确实需要使用<group>
<p id="111">5tw5t5et</p>
<p id="111">4qvtq3</p>
</group>
<p id="222">qv34tqv3</p>
<j>qv43tvq</j>
<group>
<p id="333">qv43tvq</p>
<p id="333">q34tvq43tvq</p>
<p id="333">q3434t3tvq43tvq</p>
</group>
和一个符号:
or