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

时间:2015-02-09 11:31:38

标签: dictionary clojure destructuring

假设我有一张这样的地图

{:a 1 :b 2 :c 3}

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

(mapcat (fn [[:key key-a][:value value-a]] (println "key: " key-a "\n value: " value-a )))

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

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

2 个答案:

答案 0 :(得分:6)

(seq {:a 1 :b 2 :c 3})
;([:a 1] [:b 2] [:c 3])

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

  • 无需输入订单;
  • 实际上是MapEntry s,表现为成对。

因此

(type (first {:a 1 :b 2 :c 3}))
;clojure.lang.MapEntry

您的伪代码

(mapcat (fn [[:key key-a][:value value-a]] (println "key: " key-a "\n value: " value-a )))

......需要多次修理:

  • 提供省略的最终参数 - 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}))

打印

key:  :a  value:  1
key:  :c  value:  3
key:  :b  value:  2

...和返回 nil

答案 1 :(得分:3)

当你map在地图上时,每个元素都是一个包含两个值的向量:键和值。你用这样的向量来构造每个元素:

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

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