Clojure 中是否有类似于 Python 的
any
和 all
函数的内置函数?
例如,在 Python 中,它是
all([True, 1, 'non-empty string']) == True
。
(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
在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
,因为它评估真实性
与
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