Takes an expression and a set of test/form pairs. Threads expr (via ->) through each form for which the corresponding test expression is true. Note that, unlike cond branching, cond-> threading does not short circuit after the first true test expression.
(cond-> 1 ; we start with 1 true inc ; the condition is true so (inc 1) => 2 false (* 42) ; the condition is false so the operation is skipped (= 2 2) (* 3)) ; (= 2 2) is true so (* 2 3) => 6 ;;=> 6 ;; notice that the threaded value gets used in ;; only the form and not the test part of the clause.
;; Useful when you want to conditionally evaluate expressions and thread them ;; together. For instance, the following returns a vector containing the names ;; (as symbols) of the implementing classes of obj. => (defn instance->types [obj] (cond-> [] (instance? java.util.SortedMap obj) (conj 'SortedMap) (instance? java.util.AbstractMap obj) (conj 'AbstractMap))) #'user/instance->types => (def hm (java.util.HashMap.)) #'user/hm => (instance->types hm) [AbstractMap] => (def tm (java.util.TreeMap.)) #'user/tm => (instance->types tm) [SortedMap AbstractMap]
=> (defn divisible-by? [divisor number] (zero? (mod number divisor))) #'user/divisible-by? => (defn say [n] (cond-> nil (divisible-by? 3 n) (str "Fizz") (divisible-by? 5 n) (str "Buzz") :always (or (str n)))) #'user/say => (say 1) "1" => (say 3) "Fizz" => (say 5) "Buzz" => (say 15) "FizzBuzz"
(let [x 1 y 2] (cond-> [] (odd? x) (conj "x is odd") (zero? (rem y 3)) (conj "y is divisible by 3") (even? y) (conj "y is even"))) ;=> ["x is odd" "y is even"] ;;; IS Equivalent to (let [x 1 y 2] (as-> [] <> (if (odd? x) (conj <> "x is odd") <>) (if (zero? (rem y 3)) (conj <> "y is divisible by 3") <>) (if (even? y) (conj <> "y is even") <>))) ;=> ["x is odd" "y is even"]
; Consider a code snippet that coerces any string to an integer, else noop: (let [x "123"] (if (string? x) (Integer. x) x)) ; We can reduce the repetition of `x` by using `cond->` (let [x "123"] (cond-> x (string? x) (Integer.)))
;; always returns 1 (defn f [x] 1) ;; cond-> doesn't short circuit on nil (cond-> nil true f false inc true inc) ;=> 2
;; If most of a -> is unconditional but one step is conditional, cond-> is useful: (-> {} (assoc :foo "foo") (cond-> false (assoc :truthy true)) (assoc :bar "bar")) ;; => {:foo "foo", :bar "bar"} (-> {} (assoc :foo "foo") (cond-> true ; this is the only change from above (assoc :truthy true)) (assoc :bar "bar")) ;; => {:foo "foo", :truthy true, :bar "bar"}
Takes an expression and a set of test/form pairs. Threads expr (via ->>) through each form for whi...
Threads the expr through the forms. Inserts x as the second item in the first form, making a list ...
Threads the expr through the forms. Inserts x as the last item in the first form, making a list of...
Binds name to expr, evaluates the first form in the lexical context of that binding, then binds na...
When expr is not nil, threads it into the first form (via ->), and when that result is not nil, th...
When expr is not nil, threads it into the first form (via ->>), and when that result is not nil, t...
Takes a set of test/expr pairs. It evaluates each test one at a time. If a test returns logical t...
cond->