当我学习使用快捷方式:keys
来解构地图时,这个问题就出现了。
假设我有以下地图:
(def my-hashmap {:a "A" :b "B" :c "C" :d "D"})
现在我可以参考写作的值
(let [{first-key :a second-key :b} my-hashmap]
(println first-key second-key))
我得到A B
。现在使用:keys
密钥必须与原始密钥相同(没有:
),否则clojure会返回nil
?所以,对于
(let [{:keys [first-key second-key]} my-hashmap]
(println first-key second-key))
你得到nil nil
。
我是否认为这是错误的,或者真的是在clojure中发生这种不合逻辑的事情,因为这两种方法都是指密钥,因此应该以相同的方式工作?但他们没有,因为如果我写(let [{:keys [a b]} my-hashmap] (println a b))
,我会得到正确答案!
答案 0 :(得分:4)
您无法满足第二个示例中对:keys
的要求,因为无法推断应该查找哪些单独的键,以使其值绑定到您正在使用的任意符号。
请注意,地图是关联的,但不是有序的数据结构。因此,如果您希望使用不同的名称,则需要将它们映射到可在析构化地图中查找其值的名称和类型,如您在第一个示例中所做的那样。
您可以在:keys
向量中使用在地图中具有完全限定关键字名称的符号和关键字。此外,:syms
和:strs
可用于构造符号或字符串的析构函数。
答案 1 :(得分:-1)
阿米尔,
不是问题的具体答案;地图实现了Iterable
,因此您可以在不知道密钥名称的情况下创建一个使用地图的方案:
(defn map-sequence-example
[& [[[k v] kp2 & remaining] :as mymap] ]
(println "first key = " k " first value = " v)
(println "next key pair = " kp2)
(println "remaining = " remaining)
(println "mapseq = " mymap))
(map-sequence-example (seq {:a 1 :b 2 :c 3}))
first key = :a first value = 1
next key pair = [:b 2]
remaining = ([:c 3])
mapseq = (([:a 1] [:b 2] [:c 3]))