Clojure 逆过程:键分解:从序列构造贴图

Clojure 逆过程:键分解:从序列构造贴图,clojure,Clojure,我在Clojure中写得越多,就越会遇到以下类型的模式: (定义映射键[foo-bar-baz] {:foo-foo,:bar-bar,:baz-baz}) 在某种意义上,这看起来像是一个反过程,一个解构 (让[{:keys[foo-bar-baz]}]…) 将实现 Clojure中是否有一种“内置”方式来实现类似于上述映射键的功能(将名称映射到关键字=>值)-可能用于任意长度的名称列表?没有内置这种功能,因为它不需要。与相当复杂的解构不同,在Clojure中构造映射非常简单,因此这种奇特的

我在Clojure中写得越多,就越会遇到以下类型的模式:

(定义映射键[foo-bar-baz]
{:foo-foo,:bar-bar,:baz-baz})
在某种意义上,这看起来像是一个反过程,一个解构

(让[{:keys[foo-bar-baz]}]…)
将实现


Clojure中是否有一种“内置”方式来实现类似于上述
映射键的功能(将名称映射到关键字=>值)-可能用于任意长度的名称列表?

没有内置这种功能,因为它不需要。与相当复杂的解构不同,在Clojure中构造映射非常简单,因此这种奇特的方法留给普通库使用。例如,我很久以前就写过,它反映了地图分解的三种模式:

(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])))

我发现我经常想从单个值构造一个映射,或者分解一个映射来检索单个值。在本手册中,我有一个方便的工具用于此目的,我一直在使用:

(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}


另外,我当然知道你可以用
:keys
语法进行解构,但对我来说这似乎有点不直观。

太好了,选择它是因为首先。出于兴趣,我还将我的独立思考过程添加到了问题中(我做了一些类似于你的第二个宏的事情,但只过滤了符号)。我真的不理解你添加的功能的价值:你希望从中得到什么?由于它是一个宏,您通常会手工编写它的输入。例如,由于
1
在这种情况下毫无意义,您可以省略它,而不是写一些垃圾来过滤它。Stack Overflow非常乐意回答您自己的问题,但您应该这样做作为答案(在现有答案下面有一个“回答您的问题”按钮),不是作为你问题的脚注。我已回滚您的编辑:您可以从编辑历史记录中恢复其内容,以便创建您的答案。如前所述,这是一个仅链接的答案。您包含了一些代码,但没有一个是重要的部分,即实际问题的答案。如果这个链接以某种方式损坏,那么在答案中留下一些测试用例对任何人都没有用。此外,我继续鼓励您在答复中公布Tupelo的所有权。除GitHub外,代码在此处永久可用: