Clojure: How to pass two sets of unlimited parameters?

Thoughtful example to illustrate:

(def nest1 {:a {:b {:c "foo"}}})
(def nest2 {:d {:e "bar"}})

If I wanted to connect these sockets at arbitrary levels, I could explicitly do this:

(conj (-> nest1 :a :b) (-> nest2 :d)) ; yields {:e "bar", :c "foo"}

(conj (-> nest1 :a) (-> nest2 :d)) ; yields {:e "bar", :b {:c "foo"}}

But what if I wanted to create a function that takes the "depth" nest1 and nest2 as parameters?

; Does not work, but shows what I am trying to do
(defn join-nests-by-paths [nest1-path nest2-path]
   (conj (-> nest1 nest1-path) (-> nest2 nest2-path))

And I can try to call it this way:

; Does not work
(join-nests-by-paths '(:a :b) '(:d))

This does not work. I can't just pass each "path" as a function list (or maybe I can, but I need to work with it differently in a function).

Any thoughts? TIA ... Sean

+3
source share
1 answer

Use get-in :

(defn join-by-paths [path1 path2]
  (conj (get-in nest1 path1) (get-in nest2 path2)))

user> (join-by-paths [:a :b] [:d])
{:e "bar", :c "foo"}
user> (join-by-paths [:a] [:d])
{:e "bar", :b {:c "foo"}}

Your version really does something like this:

user> (macroexpand '(-> nest1 (:a :b)))
(:a nest1 :b)

which, as you said, does not work.

get-in assoc-in update-in, . a dissoc-in - clojure.conrtrib.

( Clojure , .)

+5

Source: https://habr.com/ru/post/1733384/


All Articles