Clojure中是否内置了类似于Python的any
和all
函数的函数?
例如,在Python中,它是all([True, 1, 'non-empty string']) == True
。
答案 0 :(得分:41)
(every? f data)
[docs] 与all(f(x) for x in data)
相同。
(some f data)
[docs] 与any(f(x) for x in data)
类似,只是它返回f(x)
的值(必须是真实的),而不是只是true
。
如果你想要与Python完全相同的行为,你可以使用identity
函数,它只返回它的参数(相当于(fn [x] x)
)。
user=> (every? identity [1, true, "non-empty string"])
true
user=> (some identity [1, true "non-empty string"])
1
user=> (some true? [1, true "non-empty string"])
true
答案 1 :(得分:3)
在clojure中and
和or
与python的all
和any
非常相似,但需要注意的是(就像clojure.core/some
一样)它们会返回元素这将使它满意...因此你可以与boolean
一起使用它来转换它
(boolean (or "" nil false)) ; "" is truthy in clojure
; => true
(boolean (and [] "" {} () 0)) ; also [], {}, () and 0 are truthy
; => true
我使用boolean
代替true?
,因为后者将返回true
iff参数值为true ...所以boolean
更类似于python的bool
1}}因为它评估了真实性
与some
& every?
,and
& or
是宏,所以如果你总是希望将结果转换为布尔值,你不能简单地做(def any (comp boolean or))
,但你必须定义一个宏,如
(defmacro any [& v] `(boolean (or ~@v)))
(defmacro all [& v] `(boolean (and ~@v)))
作为宏的副作用/优点是,它们是懒惰/可以短路(就像python的and
& or
,但它们是中缀二进制运算符)
(any "" (/ 1 0))
; => true
(all nil (/ 1 0))
; => false
它们就像python的any
和all
,即使在没有参数的情况下调用
(any)
; => false
(all)
; => true
在python中:
>>> any([])
False
>>> all([])
True
如果您希望使用单个列表/序列参数调用any
/ all
,则可以执行以下操作:
(defmacro all [v] `(boolean (and ~@v)))
(all [])
; => true
(all [nil (/ 1 0)])
; => false