Andrei Belkevich
Andrei Belkevich

Reputation: 73

creating a nested clojure map by calling function with its keys and values

I am stuck with a problem. So the problem is.

Subvalues is the result of making a request with each key and each item of its value. And i want to repeat the operation once again(with 3 parameters when I make a request to the server) to achieve 4 times nested map: {first {second {third {fourth}}}}. Maybe somebody give me helpful advice how to do it.

Upvotes: 0

Views: 264

Answers (1)

Josh
Josh

Reputation: 4806

This function is a bit long-winded but does what you need it to do:

(defn rec-update
  [m f]
  (let [g (fn g [m args]
            (into {}
                  (for [[k v] m]
                    (if (instance? java.util.Map v)
                      [k (g v (conj args (name k)))]
                      [k (into {} (map #(let [args (into args [(name k) (name %)])]
                                          [(keyword %) (f args)])
                                       v))]))))]
    (g m [])))

The f parameter should be a function that takes a collection of params, and returns a vector of results. Here is a sample that picks random numbers of random responses:

(defn make-request
  [params]
  (vec (repeatedly (+ 1 (rand-int 3)) #(rand-nth ["r1" "r2" "r3"]))))

Though the below example does not demonstrate, the params given to this function will indeed be the nested values up to that point.

To use:

(def m {:first ["val1" "val2" "val3"], :second ["val4" "val5"]})

(rec-update m make-request)
=>
{:first {:val1 ["r2" "r2" "r3"], :val2 ["r2" "r2"], :val3 ["r1" "r3"]},
 :second {:val4 ["r3" "r3"], :val5 ["r2" "r1"]}}

Run it again on the result:

(rec-update *1 make-request)
=>
{:first {:val1 {:r2 ["r1" "r3" "r2"], :r3 ["r3" "r2"]},
         :val2 {:r2 ["r1" "r1"]},
         :val3 {:r1 ["r2"], :r3 ["r1" "r2" "r3"]}},
 :second {:val4 {:r3 ["r3" "r2"]}, :val5 {:r2 ["r1"], :r1 ["r2" "r3"]}}}

As you can see, any duplicate values returned from the request will only be represented once in the result map.

Upvotes: 2

Related Questions