Существуют ли встроенные функции в 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