Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assoc-if in Clojure

Tags:

clojure

Is there an "assoc-if" function in the Clojure library? I.e if a value is truthy, update a map with a given key value. I've tried to find something to this effect, but came up lacking.

(defn assoc-if   [m key value]   (if value (assoc m key value) m)) 
like image 731
Odinodin Avatar asked May 03 '13 10:05

Odinodin


2 Answers

If the goal is to avoid repeating m, you can use conj:

(conj m (when value [key value])) 

...or Clojure 1.5's new threading macros:

(-> m   (cond-> value (assoc key value))) 

If it's actually important to avoid repeating both the m and value, you'll have to write your own or reach outside clojure.core

like image 121
Chouser Avatar answered Sep 24 '22 09:09

Chouser


There is no build-in assoc-if function in Clojure, but you're not the first one who needs it. Check this link with an implementation of assoc-if by ALEX MILLER:

(defn ?assoc   "Same as assoc, but skip the assoc if v is nil"   [m & kvs]   (->> kvs     (partition 2)     (filter second)     flatten     (apply assoc m))) 

But, since flatten is recursive, it's best to replace it with something which is not (thanks to kotarak for the hint). Another problem of this implementation is that (apply assoc m) will fail on empty list. So, it's best to replace it to:

(defn ?assoc   "Same as assoc, but skip the assoc if v is nil"   [m & kvs]   (->> kvs     (partition 2)     (filter second)     (map vec)     (into m))) 
like image 25
Leonid Beschastny Avatar answered Sep 22 '22 09:09

Leonid Beschastny