Are there built in functions in Clojure similar to Python's any
and all
functions?
For example, in Python, it's all([True, 1, 'non-empty string']) == True
.
(every? f data)
[docs] is the same as all(f(x) for x in data)
.
(some f data)
[docs] is like any(f(x) for x in data)
except that it returns the value of f(x)
(which must be truthy), instead of just true
.
If you want the exact same behaviour as in Python, you can use the identity
function, which will just return its argument (equivalent to (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
In clojure and
and or
are quite similar to python's all
and any
, with the caveat that (just like clojure.core/some
) they return the element that will satifsy it... thus you can use it together with boolean
to convert it
(boolean (or "" nil false)) ; "" is truthy in clojure
; => true
(boolean (and [] "" {} () 0)) ; also [], {}, () and 0 are truthy
; => true
I use boolean
instead of true?
since the latter will return true
iff the argument is the value true... so boolean
is more akin to python's bool
in that it evaluates the truthyness
Unlike some
& every?
, and
& or
are macros, so if you always want to convert the result to a boolean, you cannot simply do (def any (comp boolean or))
but you have to define a macro like
(defmacro any [& v] `(boolean (or ~@v)))
(defmacro all [& v] `(boolean (and ~@v)))
a side-effect/advantage of being macros, is that they are lazy/can shortcircuit (just like python's and
& or
, that are infix binary operators however)
(any "" (/ 1 0))
; => true
(all nil (/ 1 0))
; => false
and they're just like python's any
and all
, even when called without arguments
(any)
; => false
(all)
; => true
in python:
>>> any([])
False
>>> all([])
True
If you prefer to have to call any
/all
with a single list/sequence argument, you can simply do:
(defmacro all [v] `(boolean (and ~@v)))
(all [])
; => true
(all [nil (/ 1 0)])
; => false
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With