用于解构映射的Clojure快捷方式

时间:2015-07-04 11:50:49

标签: clojure

当我学习使用快捷方式: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)),我会得到正确答案!

2 个答案:

答案 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]))