:keys 解构的逆过程:从序列构造映射
Inverse process of :keys destructuring: construct map from sequence
我用 Clojure 写的越多,我就越遇到以下这种模式:
(defn mapkeys [foo bar baz]
{:foo foo, :bar bar, :baz baz})
在某种意义上,这看起来像是解构的逆过程
(let [{:keys [foo bar baz]}] ... )
会实现。
Clojure 中是否有一种“内置”方式来实现与上述类似的东西 mapkeys
(将名称映射到关键字 => 值)- 可能是任意长度的列表名字?
没有内置这样的东西,因为它不需要。与相当复杂的解构不同,在 Clojure 中构建映射非常简单,因此普通库可以采用奇特的方式来实现。例如,我很久以前写过 flatland.useful.map/keyed
,它反映了 map 解构的三种模式:
(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))))))
但是如果你只关心关键字,而不需要文档字符串,它可能会更短:
(defmacro keyed [names]
(into {}
(for [n names]
[(keyword n) n])))
我发现我经常想要从单个值构建映射或解构映射以检索单个值。在 Tupelo Library I have a handy pair of functions 中,我一直使用的目的是:
(ns tst.demo.core
(:use demo.core tupelo.core tupelo.test))
(dotest
(let [m {:a 1 :b 2 :c 3}]
(with-map-vals m [a b c]
(spyx a)
(spyx b)
(spyx c)
(spyx (vals->map a b c)))))
结果
; destructure a map into values
a => 1
b => 2
c => 3
; construct a map
(vals->map a b c) => {:a 1, :b 2, :c 3}
P.S。当然,我知道您可以使用 :keys
语法进行解构,但对我来说它似乎总是有点不直观。
我用 Clojure 写的越多,我就越遇到以下这种模式:
(defn mapkeys [foo bar baz]
{:foo foo, :bar bar, :baz baz})
在某种意义上,这看起来像是解构的逆过程
(let [{:keys [foo bar baz]}] ... )
会实现。
Clojure 中是否有一种“内置”方式来实现与上述类似的东西 mapkeys
(将名称映射到关键字 => 值)- 可能是任意长度的列表名字?
没有内置这样的东西,因为它不需要。与相当复杂的解构不同,在 Clojure 中构建映射非常简单,因此普通库可以采用奇特的方式来实现。例如,我很久以前写过 flatland.useful.map/keyed
,它反映了 map 解构的三种模式:
(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))))))
但是如果你只关心关键字,而不需要文档字符串,它可能会更短:
(defmacro keyed [names]
(into {}
(for [n names]
[(keyword n) n])))
我发现我经常想要从单个值构建映射或解构映射以检索单个值。在 Tupelo Library I have a handy pair of functions 中,我一直使用的目的是:
(ns tst.demo.core
(:use demo.core tupelo.core tupelo.test))
(dotest
(let [m {:a 1 :b 2 :c 3}]
(with-map-vals m [a b c]
(spyx a)
(spyx b)
(spyx c)
(spyx (vals->map a b c)))))
结果
; destructure a map into values
a => 1
b => 2
c => 3
; construct a map
(vals->map a b c) => {:a 1, :b 2, :c 3}
P.S。当然,我知道您可以使用 :keys
语法进行解构,但对我来说它似乎总是有点不直观。