创建一个将其参数传递为:另一个函数的键的函数

时间:2013-05-22 22:58:54

标签: function clojure hashmap

我有一个采用以下形式的功能

(defn foo [& {:keys [x y z]}]
  ...)

我想创建一个只占用y和z键的函数,但总是给x赋予相同的值。我可以像这样写

(defn bar [& {:keys [y z]}]
  (foo :x "blah" :y y :z z))

我唯一的问题是我必须再次重复{:keys ...}位,并且实际的函数foo有更多的键,这可能在将来发生变化。有没有什么方法可以让bar接受任何键值对,并将它们全部传递给foo,同时确保x保持不变?

3 个答案:

答案 0 :(得分:2)

这有效并覆盖传递给:x的任何bar值:

(defn foo [& {:keys [ x y ]}]
   [x y])

(defn bar [ & args ]
   (apply foo (concat args [:x "blah"])))

答案 1 :(得分:2)

(defn bar [& {:keys [y z] :as args}]
  (apply foo (apply concat (assoc args :x "blah"))))

答案 2 :(得分:1)

当您使用&符号(&)时,您声明了一个可变参数函数。 你可能不需要你的函数是可变的。 你可以这样做:

(defn foo [{:keys [x y z]}]
  [x y z])

(defn bar [{:keys [y z] :as args}]  
  (foo (assoc args :x "blah")))

您将使用以下地图致电bar(bar {:y 20 :z 10})。如果您确实需要bar作为可变函数,则可以执行此操作(foo与上面相同):

(defn bar [& {:keys [y z] :as args}]
   (foo (assoc args :x "blah"))

您将继续这样致电bar(bar :y 10 :z 20)。您也可以使foo变量,但您必须使用类似(flatten (map list (keys args) (vals args))))的内容重新创建参数列表。