我在 Clojure 中写得越多,就越会遇到以下类型的模式:
(defn mapkeys [foo bar baz]
{:foo foo, :bar bar, :baz baz})
Run Code Online (Sandbox Code Playgroud)
从某种意义上说,这看起来像是解构的逆过程。
(let [{:keys [foo bar baz]}] ... )
Run Code Online (Sandbox Code Playgroud)
会实现。
Clojure 中是否有一种“内置”方式来实现与上述类似的东西mapkeys(将名称映射到关键字=> 值)——也许是针对任意长度的名称列表?
没有内置这样的东西,因为它不需要。与相当复杂的解构不同,在 Clojure 中构造映射非常简单,因此为普通库留下了奇特的方法。比如我很早以前写过的flatland.useful.map/keyed,反映了地图解构的三种模式:
(let [transforms {:keys keyword
:strs str
:syms identity}]
(defmacro keyed
"Create a map in which, for each symbol S in vars, (keyword S) is a
key mapping to the value of S in the current scope. If passed an optional
:strs or :syms first argument, use strings or symbols as the keys instead."
([vars] `(keyed :keys ~vars))
([key-type vars]
(let [transform (comp (partial list `quote)
(transforms key-type))]
(into {} (map (juxt transform identity) vars))))))
Run Code Online (Sandbox Code Playgroud)
但是如果你只关心关键字,而不需要一个文档字符串,它可能会更短:
(defmacro keyed [names]
(into {}
(for [n names]
[(keyword n) n])))
Run Code Online (Sandbox Code Playgroud)