如何在不知道Clojure中的键的情况下将地图构造成键值对?

haw*_*eye 3 dictionary clojure destructuring

假设我有一张这样的地图

{:a 1 :b 2 :c 3}
Run Code Online (Sandbox Code Playgroud)

我想像这样映射(注意 - 非工作伪代码):

(mapcat (fn [[:key key-a][:value value-a]] (println "key: " key-a "\n value: " value-a )))
Run Code Online (Sandbox Code Playgroud)

如果没有首先获取函数的键,映射它们并从函数中读回它,这是否可行?

我的问题是:如何在不知道Clojure中的键的情况下将地图解构为键值对?

Thu*_*ail 7

(seq {:a 1 :b 2 :c 3})
;([:a 1] [:b 2] [:c 3])
Run Code Online (Sandbox Code Playgroud)

调用seq地图会为您提供一系列键值对.该seq调用通常是隐含的.

  • 不必在输入的顺序;
  • 实际上是MapEntrys,表现为成对.

从而

(type (first {:a 1 :b 2 :c 3}))
;clojure.lang.MapEntry
Run Code Online (Sandbox Code Playgroud)

你的伪代码

(mapcat (fn [[:key key-a][:value value-a]] (println "key: " key-a "\n value: " value-a )))
Run Code Online (Sandbox Code Playgroud)

......需要多次维修:

  • 提供省略的最终参数 - 应用的集合map .
  • 只需将每个结构拆分MapEntry成一对即可获得
    关键和价值.
  • 使用map而不是mapcat将函数应用于每对.幸运的是mapcat,它完全有效.
  • 使用dorun强制顺序进行评估和它这样做把它扔掉.REPL为您做前者,但正在运行的应用程序不需要.

这给了我们

(dorun
 (map 
  (fn [[key-a value-a]] (println "key: " key-a " value: " value-a ))
  {:a 1 :b 2 :c 3}))
Run Code Online (Sandbox Code Playgroud)

哪个打印

key:  :a  value:  1
key:  :c  value:  3
key:  :b  value:  2
Run Code Online (Sandbox Code Playgroud)

...并返回 nil.


Mar*_*Dow 5

当您map浏览地图时,每个元素都是一个包含两个值的向量:键和值。您可以使用如下向量解构每个元素:

(def m {:a 1 :b 2 :c 3})
(map (fn [[key value]] (str "key: " key " > value: " value-a)) m)
Run Code Online (Sandbox Code Playgroud)

请注意,传递给的函数map返回一个 String 值,而不是您对 的调用println,因为我们试图通过将函数应用于每个值来转换传入的集合。map您可以传递to返回的集合prn来调试该值,尽管 REPL 无论如何都会为您打印出来。