如何将 hashmap 的所有键值对传递给函数(而不传递整个 hashmap)?

How to pass all key value pairs of a hashmap into a function (without passing the whole hashmap)?

我想将 hashmap 的所有 key-val 对传递给一个函数,而不是整个 hashmap。

所以我有一个我无法更改的函数,它看起来像这样:

(defn foo [a b c & {:keys [x y z]}]
  (println x y z))

我有一个散列图,其中包含可变数量的键和值。假设一个实例是:

(def bar {:d 1
          :e 2
          :x "x"
          :y "y"})

如何在不传递整个 hashmap 的情况下将所有键值对传递给 foo? 我想做

(foo "a" "b" "c" 
     :d 1
     :e 2
     :x "x"
     :y "y")

如果 foo 是您“继承”的东西,那么一种方法是:

(apply foo "a" "b" "c" (into [] cat bar))

这会“拉平”键值并应用调用。

如果您只想传递所需的内容,您可以使用 select-keys bar第一。

如果 foo 是您自己写的,请重新考虑。这个 pattern 乍一看很适合人类消费,但它变得 很难只通过地图。所以我的建议是:只允许 作为第四个参数传递的地图。如果地图在那里是可选的, 提供 foo 的另一个 arity 版本,它传递一个空映射。

select-keys 可用于将映射修剪为所需的键:

(apply foo "a" "b" "c" (apply concat (select-keys bar [:x :y :z])))

或者,一个大胆的解决方法是使用 Clojure 1.11.0-alpha1 或更高版本 supports keyword arguments to be passed as maps。有了这个你可以简单地做:

(foo "a" "b" "c" bar)