Clojure:如何传递两组无界参数?

scr*_*tty 3 clojure

举例说明:

(def nest1 {:a {:b {:c "foo"}}})
(def nest2 {:d {:e "bar"}})
Run Code Online (Sandbox Code Playgroud)

如果我想在任意级别上联合这些巢,我可以明确地这样做:

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

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

但是如果我想创建一个接受nest1和nest2的"深度"作为参数的函数呢?

; 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))
Run Code Online (Sandbox Code Playgroud)

我可能试着这样称呼它:

; Does not work
(join-nests-by-paths '(:a :b) '(:d))
Run Code Online (Sandbox Code Playgroud)

这不起作用.我不能简单地将每个"路径"作为列表传递给函数(或者我可以,但需要在函数中以不同的方式使用它).

有什么想法吗?TIA ......肖恩

Bri*_*per 5

使用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"}}
Run Code Online (Sandbox Code Playgroud)

您的版本实际上是这样做的:

user> (macroexpand '(-> nest1 (:a :b)))
(:a nest1 :b)
Run Code Online (Sandbox Code Playgroud)

如你所说,哪个不起作用.

get-in有朋友assoc-inupdate-in所有与地图的嵌套映射工作.dissoc-in在clojure.conrtrib中有一个地方.

(在Clojure中,当您传递连续的事物组时,使用向量而不是引用列表更加惯用.)