是否有一个 Clojure 函数接受一个映射并返回一系列交替的键和值?

Jam*_*lay 4 clojure destructuring

给定一个 map {:a 1 :b [2,3]},是否有一个内置函数可以返回序列(:a 1 :b [2,3])

用例是将选项映射应用于函数,该函数对参数列表的其余部分进行映射解构绑定。这是 core.cache 中的一个示例。这是一个人为的例子来说明:

(defn make-car [& {:as options}] (assoc options :car true))
(make-car :color "red" :speed "fast")
; => {:car true, :speed "fast", :color "red"}
Run Code Online (Sandbox Code Playgroud)

现在如果我们想分别管理选项和apply它们到函数中,我们有一个问题:

(def options {:color "red" :speed "fast"})
(apply make-car options)
; => {:car true, [:speed "fast"] [:color "red"]}
Run Code Online (Sandbox Code Playgroud)

...因为当然seq地图的 是其键值对的序列。这是我想出的最好的:

(apply make-car (interleave (keys options) (vals options)))
; => {:car true, :speed "fast", :color "red"}
Run Code Online (Sandbox Code Playgroud)

这是非常可怕的。我知道我可以让我自己的函数来做到这一点,但我很惊讶我没有找到内置的东西。如果没有内置的东西,那么我可能想避免在库代码中像这样解构参数列表。

Eve*_*man 5

这个怎么样:

(reduce concat {:a 1 :b [2,3]})
(:a 1 :b [2 3])
Run Code Online (Sandbox Code Playgroud)

更新基于从amalloy评论。Apply 效率更高(至少在 1.4 中),并达到相同的结果!

(apply concat {:a 1 :b [2,3]})
(:a 1 :b [2 3])
Run Code Online (Sandbox Code Playgroud)

  • `(reduce concat)` 对于大序列非常危险,而对于小序列来说效率低下。改用`(apply concat)`。 (2认同)