从 clojure 中的哈希映射中获取指定索引处的值

Getting value at specified index from a hash map in clojure

我正在使用 Clojure 做我的第二个家庭作业,但我很难从哈希映射中获取指定索引处的值。目前我有一个函数来创建一个表示图形的哈希映射向量。然后我对该向量进行索引以获取表示节点的特定哈希映射,特别是节点与其他节点的连接;因此

homework2.core> (reg-ring-lattice 5 2)  
[#{1 4} #{0 2} #{1 3} #{4 2} #{0 3}] 
homework2.core> ((reg-ring-lattice 5 2) 2)
#{1 3} 

我的问题是遍历哈希映射本身中的值。我特别想从散列映射中检索第 n 个索引。这是我试过的

homework2.core> ((reg-ring-lattice 5 2) 3) 
#{4 2}
homework2.core> (((reg-ring-lattice 5 2) 3) 0) 
nil
homework2.core> (get ((reg-ring-lattice 5 2) 3) 0) 
nil

我进行了搜索,但目前我对 Clojure 及其 keywords/jargon 的了解有限。

第一个问题是,我是否用它们的专有名称来称呼这些集合。其次,如何在我称为哈希映射的指定索引处检索值?

这些不是散列 MAPS,而是散列 SETS,它们没有排序。您将在 sequential/indexed 访问权限上获得一个 "random" 元素。例如

user=> (first #{1 2 3 4 5})
1
user=> (second #{1 2 3 4 5})
4

散列映射是一个字典,key/value 对。它们出现在花括号 -> {} 包围的输出中。集合类似于列表,但必须包含唯一项。集合显示在输出中,周围是带有大括号的八角形 -> #{}。向量是包含索引序列中项目的结构。它们出现在方括号中的输出中 -> [].

参见hash-maps at the clojure.org docs, sets at the clojure.org docs, and vectors at the clojure.org docs

您的 reg-ring-lattice 函数正在返回集合向量。像您一样对由数字组成的集合进行索引没有多大意义,所以让我回顾一下您在示例代码块中所做的事情。

;This output is a vector of sets
(reg-ring-lattice 5 2)
[#{1 4} #{0 2} #{1 3} #{4 2} #{0 3}]

;This output exploits the fact that vectors implement IFn (see the doc links)
; Surrounding the call in another set of parens makes another call the argument
; of which is '2'. You seem to have a good grasp on all this so far.
((reg-ring-lattice 5 2) 2) ; returns the item at index 2 in the vector
#{1 3}

;This is exactly the same as the above except for getting the item at index 3.
((reg-ring-lattice 5 2) 3)
#{4 2}

;This is what doesn't make sense. Sets are functions of their members. They
;aren't indexed like vectors are
(((reg-ring-lattice 5 2) 3) 0)
; What you are saying here is 'give me item 0, not index 0, out of the set
; returned from looking into the vector at index 3 or nil if not found'.
; It would work if your set had a 0 in it or if you did this:
(((reg-ring-lattice 5 2) 3) 4) ; -> returns 4
; but it's not too helpful because you already know what you're looking up.

;Instead, this is where you start treating the returned set like a list
(first ((reg-ring-lattice 5 2) 3)) ; -> returns 4
(second ((reg-ring-lattice 5 2) 3)) ; -> returns 2

有一点要警惕集合,如果生成排序集合可以忽略,它们可能不会排序。上次是第一个,下次可能不是第一个。另一件需要注意的事情是重复。集合中的每个项目都必须是唯一的。你不能有这样的集合 -> #{4 4}.

正如其他人所指出的,您使用的是 集合 的向量,而不是地图向量。

将集合作为函数调用将 return 参数,如果它在集合中,否则 nil:

(#{2 3 4} 1) ;nil
(#{2 3 4} 2); 2

您想从集合中检索第 n 个元素:

(nth (seq #{2 3 4}) 1)
;3

订单可能不是您所期望的:

(seq #{4 2 3})
; (2 3 4)

但是你为什么想要第 n 个元素呢?您可以通过调用 seq 来枚举集合的元素(如果您使用的是 mapreduce 等函数,则隐式调用)。如果您向我们展示您正在尝试做什么,那么很可能有更惯用的方法来做到这一点。 nth 很慢 - 它逐个元素地告诉序列。

顺便说一句,通过使用集合的 向量 ,您将自己绑定到节点标记为 0n 的图形。 map 集合通常是更好的选择:

{4 #{0 3}, 3 #{2 4}, 2 #{1 3}, 1 #{0 2}, 0 #{1 4}}

...而不是...

[#{1 4} #{0 2} #{1 3} #{4 2} #{0 3}]