Существуют ли встроенные функции в Clojure, аналогичные функциям Python any
и all
?
Например, в Python он all([True, 1, 'non-empty string']) == True
.
Существуют ли встроенные функции в 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
, если аргументом является значение true... так что boolean
более сродни python bool
тем, что он оценивает правду
В отличие от some
и every?
, and
и or
являются макросами, поэтому, если вы всегда хотите преобразовать результат в логическое, вы не можете просто сделать (def any (comp boolean or))
, но вы должны определить макрос как
(defmacro any [& v] `(boolean (or [email protected])))
(defmacro all [& v] `(boolean (and [email protected])))
побочным эффектом/преимуществом макросов является то, что они являются ленивыми/могут замыкаться (как и 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 [email protected])))
(all [])
; => true
(all [nil (/ 1 0)])
; => false