ClojureDocs

Nav

Namespaces

some

clojure.core

Available since 1.0 (source)
  • (some pred coll)
Returns the first logical true value of (pred x) for any x in coll,
else nil.  One common idiom is to use a set as pred, for example
this will return :fred if :fred is in the sequence, otherwise nil:
(some #{:fred} coll)
15 Examples
;; 2 is even, so `some` stops there, 3 and 4 are never tested
(some even? '(1 2 3 4))
;;=> true

;; they are all odd, so not true, i.e. nil
(some even? '(1 3 5 7))
;;=> nil
(some true? [false false false])
;;=> nil

(some true? [false true false])
;;=> true

(some true? [true true true])
;;=> true
(some #(= 5 %) [1 2 3 4 5])
;;=> true

(some #(= 5 %) [6 7 8 9 10])
;;=> nil

(some #(not= 5 %) [1 2 3 4 5])
;;=> true

(some #(not= 5 %) [6 7 8 9 10])
;;=> true
;; the first logical true value is returned, i.e. anything but nil and false
;; when return nil if its predicate is logical false.
(some #(when (even? %) %) '(1 2 3 4))
;;=> 2
;; a hash acts as a function returning nil when the
;; key is not present and the key value otherwise.
(some {2 "two" 3 "three"} [nil 3 2])
;;=> "three"

;; there is nothing special about the 'nil' in the collection,
;; it is still being used as a key to find its corresponding value in the hash.
(some {nil "nothing" 2 "two" 3 "three"} [nil 3 2])
;;=> "nothing"

;; the hash (as function) returns a nil for the key of '3',
;; therefore 'some' keeps inspecting the collection,
;; returning the next logical true value.
(some {2 "two" 3 nil} [nil 3 2])
;;=> "two"
;; `some` can be used in place of `(first (filter ...))` in most cases.
(first (filter even? [1 2 3 4]))
;;=> 2

;; `some` returns exactly one item or `nil` if nothing is found.
(some #(when (even? %) %) [1 2 3 4])
;;=> 2
;; find whether a word is in a list of words.
(def word "foo")
(def words ["bar" "baz" "foo" ""])
(some (partial = word) words)
;;=> true
;; here we see sets being used as a predicate
;; the first member of the collection that appears in the set is returned

(some #{2} (range 0 10))      ;;=> 2
(some #{6 2 4} (range 0 10))  ;;=> 2
(some #{2 4 6} (range 3 10))  ;;=> 4
(some #{200} (range 0 10))    ;;=> nil

;; Be careful—`nil` or `false` can occasionally be returned on success
(some #{nil} [1 nil 2 false 3])
;;=> nil

;; If you are testing for the presence of `nil` in a collection
(some nil? [1 nil 2 false 3])
;;=> true

;; If you are testing for the presence of `false` in a collection
(some false? [1 nil 2 false 3])
;;=> true

;; If you are testing for the presence of "falsey" in a collection
(some not [1 nil 2 false 3])
;;=> true
;; if you have a case where the predicate arguments are fixed/known, 
;; but the predicate function isn't:
;; coll can supply the predicate function instead of the predicate arguments

;; define the function 'not equal' (ne)
(defn ne [n1 n2] (not= n1 n2))
;;=> #'user/ne

(some #(% 3 7) (list ne))
;;=>true

(some #(% 3 3) (list ne))
;;=>nil


;; extending the previous example: supplying multiple functions.
(defn ne [n1 n2] (not= n1 n2)) 
;;=> #'user/ne

;; function to check if the sum is less than 'limit'
(defn sumlt [limit n1 n2] (> limit (+ n1 n2))) 
;;=>'user/sumlt

(some #(% 3 7) (list ne #(sumlt 10 %1 %2)))   
;;=>true

(some #(% 3 3) (list ne #(sumlt 10 %1 %2)))   
;;=>true

(some #(% 7 7) (list ne #(sumlt 10 %1 %2)))   
;;=>nil

;; same, but one of the functions returns a value instead a boolean.
(some #(% 3 7) (list ne (fn [n1 n2] (+ n1 n2))))                 
;;=>true

(some #(% 7 7) (list ne (fn [n1 n2] (+ n1 n2))))                 
;;=>14

;; the importance of order of the function list.
(some #(% 7 7) (list ne #(sumlt 10 %1 %2) (fn [n1 n2] (+ n1 n2)))) 
;;=>14

(some #(% 7 7) (list ne (fn [n1 n2] (+ n1 n2)) #(sumlt 10 %1 %2))) 
;;=>14

(some #(% 3 3) (list ne #(sumlt 10 %1 %2) (fn [n1 n2] (+ n1 n2)))) 
;;=>true

(some #(% 3 3) (list ne (fn [n1 n2] (+ n1 n2)) #(sumlt 10 %1 %2))) 
;;=>6
;;if you want to return the element the caused the predicate to return true
;;use the "and" function on the predicate and the argument:

(some #(and (even? %) %) [1 3 5 7 8 2])
;;=> 8
;; As an alternative to the above usage of `and`, I prefer to use `if`
;; in such cases; I think it’s slightly clearer:

(some #(if (even? %) %) [1 3 5 7 8 2])
;;=> 8
;; `some` can be an alternative for `apply or`
(def v [nil false 5 nil 7])

;; (apply or v)
;; java runtime exception because or is macro

(some identity v)
;;=> 5

;; Source - lamdaisland episode
;; https://lambdaisland.com/episodes/clojure-core-some
(defn get-pred
  "Returns the first element of coll that satisfies the predicate f. 
  A behavior you'd expect from a typical 'find' function."
  [f coll]
  (some #(when (f %) %) coll))

user=> (get-pred #(> (count %) 5)
                 ["a" "b" "the answer" "wrong"])
;;=> "the answer"
See Also

Returns true if (pred x) is logical true for every x in coll, else false.

Added by pauldoo

Returns false if (pred x) is logical true for any x in coll, else true.

Added by shockbob

Returns a lazy sequence of the non-nil results of (f item). Note, this means false return values w...

Added by Radford Smith

Returns a lazy sequence of the non-nil results of (f index item). Note, this means false return va...

Added by Radford Smith

Takes a set of predicates and returns a function f that returns the first logical true value retur...

Added by alilee

When expr is not nil, threads it into the first form (via ->), and when that result is not nil, th...

Added by timgilbert

Returns true if key is present in the given collection, otherwise returns false. Note that for nu...

Added by MicahElliott

Returns true if x is not nil, false otherwise.

Added by MicahElliott

bindings => binding-form test If test is not nil, evaluates then with binding-form bound to the ...

Added by MicahElliott

bindings => binding-form test When test is not nil, evaluates body with binding-form bound to th...

Added by MicahElliott
1 Note
    By , created 12.5 years ago

    Be careful about using sets as predicates if you don't know what is in the set. In particular,

    (#{nil} nil)
    is
    nil
    and
    (#{false} false)
    is
    false
    Consider using
    contains?
    instead.