【问题标题】:Is there a threaded way to perform an "or" (or any test) condition in clojure?在clojure中是否有一种线程方式来执行“或”(或任何测试)条件?
【发布时间】:2019-05-15 20:35:12
【问题描述】:

类似的东西:

(or->
    "foobar"
    (clojure.string/starts-with? "foo")
    (clojure.string/starts-with? "bar"))

=> true

如果不是,用多个 ors/ands 执行测试的惯用方法是什么?

【问题讨论】:

标签: clojure


【解决方案1】:

我会在这里使用some。它本质上是一个序列友好的or 检查,可以在所有条件基本相同时帮助减少重复:

(some #(clojure.string/starts-with? "foobar" %)
      ["foo" "bar"])

它使用提前回报。


and 等效于 some 将是 every?

(every? odd? [3 5 9])
=> true

【讨论】:

    【解决方案2】:

    我们需要将第一个参数插入到所有连续的子句中,然后再计算它们。所以解决方案必须是宏。如果我们准备不做语法检查,我们可以非常简洁地定义它:

    (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 表单,我们为gensym 插入一个let 表单:

    (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 意义上的线程,它总是执行所有线程子句。

    【讨论】:

      【解决方案3】:

      在一般情况下,您确实需要使用or 和一个符号:

      (defn check [val]
        (or
          (= val "foobar")
          (clojure.string/starts-with? val "foo")
          (clojure.string/starts-with? val "bar")))
      
      (check "foobar") => true
      (check "foosball") => true
      (check "barbell") => true
      (check "egg-foo-yung") => false
      

      【讨论】:

        猜你喜欢
        • 2018-08-22
        • 2018-04-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-11
        • 2013-11-27
        • 2013-10-25
        • 2012-04-02
        相关资源
        最近更新 更多