Clojure: How to apply a function to a subset of entries in a hash map?

I am not Clojure and am trying to figure out how to do this.

I want to create a new hash map that applies a function to the elements for a subset of the keys in the hash map. What is the best way to do this?

(let 
   [my-map {:hello "World" :try "This" :foo "bar"}]
   (println (doToMap my-map [:hello :foo] (fn [k] (.toUpperCase k)))

This will then lead to a map with something like

{:hello "WORLD" :try "This" :foo "BAR"}
+5
source share
3 answers
(defn do-to-map [amap keyseq f]
  (reduce # (assoc% 1% 2 (f (% 1% 2))) amap keyseq))

Structure:

. Clojure - ; , , . , , :

(some-map some-key)

, f. , , :

(f (some-map some-key))

-, "" . , assoc :

(assoc some-map some-key (f (some-map some-key)))

( "" , -, , , - , assoc. Clojure, - , assoc .)

assoc , . - . - , "" . - "" . , , , -, "". , reduce.

  • reduce - , : "", , "" ; , , .
  • reduce - , fn.
  • reduce - , fn .

:

(reduce fn-to-update-values-in-our-map 
        initial-value-of-our-map 
        collection-of-keys)

fn-to-update-values-in-our-map - assoc , :

(fn [map-so-far some-key] (assoc map-so-far some-key (f (map-so-far some-key))))

, reduce:

(reduce (fn [map-so-far some-key] (assoc map-so-far some-key (f (map-so-far some-key))))
        amap
        keyseq)

Clojure : #(...) - fn, , %1 , %2 .. fn :

#(assoc %1 %2 (f (%1 %2)))

:

(reduce #(assoc %1 %2 (f (%1 %2))) amap keyseq)
+24
(defn doto-map [m ks f & args]
  (reduce #(apply update-in %1 [%2] f args) m ks))

user=> (doto-map {:a 1 :b 2 :c 3} [:a :c] + 2)
{:a 3, :b 2, :c 5}

, .

+4

The following seems to work:

(defn doto-map [ks f amap]
  (into amap
    (map (fn [[k v]] [k (f v)])
         (filter (fn [[k v]] (ks k)) amap))))

user=> (doto-map #{:hello :foo} (fn [k] (.toUpperCase k)) {:hello "World" :try "This" :foo "bar"})
{:hello "WORLD", :try "This", :foo "BAR"}

There may be a better way to do this. Maybe someone can come up with a good one-liner :)

+1
source

All Articles