假设需要检查参数是否通过给定谓词集合的一个真值测试。
codewise:
<body>
<input type="text" name="item" id="txt_search" list="item_list">
<datalist id="item_list">
<?php
foreach($arr as $a)
{
echo "<option>".$a['product']."</option>";
//$a['id']
}
?>
</datalist>
</body>
由于(fn [x]
(or (pred1 x) (pred2 x) (pred3 x) (pred4 x)))
的实施,这是第一个真正价值之后的短路。按照预期。
如何使用谓词集合重写:
[pred1 pred2 pred3 pred4]
一种时髦的方式是:
or
事实证明,这个不会短路。可能是由于Clojure对懒惰序列的分块。
我们可以做得更好吗?
答案 0 :(得分:4)
clojure具有some-fn
功能:
user> ((some-fn true? false? nil?) true)
true
user> ((some-fn false? nil?) true)
false
或您的情况:
user> (defn any-pred? [x preds]
((apply some-fn preds) x))
另一种经典的方法是递归地执行:
user> (defn any-pred? [x preds]
(when-let [[pred & preds] (seq preds)]
(or (pred x) (any-pred? x preds))))
user> (any-pred? true [false?])
nil
user> (any-pred? true [true?])
true
user> (any-pred? true [false? true?])
true
user> (any-pred? true [false? nil?])
nil
user> (any-pred? true [false? nil? true?])
true
答案 1 :(得分:0)
当我需要短路时,我会使用reduce减少。
(defn any-valid? [w & pred-fn-coll]
(reduce (fn [v pf]
(if (pf w)
(reduced true)
v)) false pred-fn-coll))
(any-valid? 1 even? odd?)
;=> true
(any-valid? 1 even? even?)
;=> false
答案 2 :(得分:0)
我认为这是map
正在你的解决方案中进行分块。
尝试
(defn any-true? [preds]
(fn [x]
(loop [preds preds]
(and (seq preds)
(or ((first preds) x)
(recur (rest preds)))))))
((any-true? [odd? even?]) 3) ;true
((any-true? []) 3) ;nil
((any-true? [even?]) 3) ;nil
((any-true? [odd? #(/ % 0)]) 3) ;true
最后一个例子表明评估是懒惰的。
答案 3 :(得分:0)
可替换地,
(defn somep? [x [p & ps :as preds]]
(if-not (empty? preds)
(or (p x) (somep? x ps))))
或
(defn somep? [x [p & ps :as preds]]
(if-not (empty? preds)
(let [res (p x)]
(if-not res
(recur x ps)
res))))