用于分解贴图的Clojure快捷方式

用于分解贴图的Clojure快捷方式,clojure,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)) 我得到了ab。现在使用:键时,键必须与原始键相同(没有:),否则clojure将返回nil?那么,为了 (let [{:k

当我学习如何使用快捷键
: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))
我得到了
ab
。现在使用
:键
时,键必须与原始键相同(没有
),否则clojure将返回
nil
?那么,为了

(let [{:keys [first-key second-key]} my-hashmap] 
    (println first-key second-key))
你会得到
nil-nil


我是否认为这是错误的,或者在clojure中真的发生了这种不合逻辑的事情,因为这两种方法都是用来引用键的,因此应该以相同的方式工作?但是他们没有,因为如果我写
(让[{:keys[ab]}我的hashmap](println a b))
我会再次得到正确的答案

无法满足第二个示例中对
:键的要求,因为无法推断应查找哪些单独的键,以将其值绑定到您正在使用的任意符号

请注意,映射是关联的,但不是有序的数据结构。因此,如果您希望使用不同的名称,则需要将它们映射到名称和类型,并且可以在析构函数映射中查找它们的值,就像您在第一个示例中所做的那样

您可以在
:keys
向量中使用符号和关键字,它们在地图中具有关键字的完全限定名称。此外,
:syms
:strs
可以对符号或字符串键进行析构函数。

Amir

然而,这不是问题的具体答案;地图实现了
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]))

(让[{:keys[first key second key]}我的hashmap](println first key second key))
中,您希望将
第一个键
第二个键
绑定到什么?地图上的钥匙不是按顺序排列的,所以你必须按名字绑定。我想应该按顺序排列吗?我是说
(let[{:keys[ab]}my hashmap](println a b))
(let[{:keys[first key second key]}my hashmap](println first key second key))
之间到底有什么区别,因为在这两种情况下
ab
first key second key
都是刚刚引入的新符号?那么clojure看到
AB
时是否认为这些密钥看起来与原始密钥相似,所以它们被接受了?!(我不认为是这样!)我在这里找到了示例:(在快捷方式下)
keys
表单在给定的映射中查找关键字键,并将它们绑定到相应的名称
(让[{:keys[ab]}m)
a
绑定到key
的值:a
b
绑定到
m
中的key
:b
。因此,是的,绑定是按名称而不是按位置进行的,因为hash-map.hm中没有键排序的概念,这有点奇怪……这里的问题是这样的(当人们说“哈希映射中没有键排序的概念”时,意思是通过向映射中添加一个新键,可以使键的顺序完全改变。
(def m{:a0:b1:c2:d3:e4:f5:g6:h7:i8})
(键m)
(:e:g:c:h:d:f:i:a)
(键)(assocm:j9))
=>
(:e:g:c:j:h:b:d:f:i:a)
是的,key order有标准的免责声明,但我提供的示例中的处理不依赖于顺序,也不依赖于k/v的数量。这是seq destructoring,而不是map destructoring。它没有回答问题。这有什么意义?真的Leon吗?这是一种使用排序来破坏map的替代方法钥匙未知的情况。这也是与您的回答中的第一段相反的更动态的推断或钥匙识别的基础。