假设我有一张这样的地图
{:a 1 :b 2 :c 3}
我想像这样映射这个(注意 - 非工作伪代码):
(mapcat (fn [[:key key-a][:value value-a]] (println "key: " key-a "\n value: " value-a )))
如果不先获取函数的键,映射这些键并从函数中读取它们,这是否可能?
我的问题是:如何在不知道 Clojure 中的键的情况下将映射分解为键值对?
假设我有一张这样的地图
{:a 1 :b 2 :c 3}
我想像这样映射这个(注意 - 非工作伪代码):
(mapcat (fn [[:key key-a][:value value-a]] (println "key: " key-a "\n value: " value-a )))
如果不先获取函数的键,映射这些键并从函数中读取它们,这是否可能?
我的问题是:如何在不知道 Clojure 中的键的情况下将映射分解为键值对?
(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
。
当你map
在地图上时,每个元素都是一个包含两个值的向量:键和值。你用这样的向量解构每个元素:
(def m {:a 1 :b 2 :c 3})
(map (fn [[key value]] (str "key: " key " > value: " value-a)) m)
请注意,传递给的函数map
返回一个字符串值,而不是您的调用println
,因为我们试图通过对每个值应用一个函数来转换传入的集合。您可以传递 to 返回的集合map
来prn
调试该值,尽管 REPL 无论如何都会为您打印出来。