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

时间:2015-02-20 06:06:21

标签: 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及其关键词/术语的了解有限。

第一个问题是,我是否用他们的名字来称呼这些收藏品。其次,如何在我调用hashmap的指定索引处检索值?

3 个答案:

答案 0 :(得分:1)

那些没有散列MAPS但是散列SETS并且它们没有排序。您将获得顺序/索引访问的“随机”元素。 E.g。

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

答案 1 :(得分:1)

哈希映射是字典,键/值对。它们出现在用花括号包围的输出中 - > {}。集合类似于列表但必须包含唯一的项目。集合显示在由带有花括号的octothorpe包围的输出中 - > #{}。向量是包含索引序列中的项的结构。它们出现在用方括号包围的输出中 - > []。

请参阅hash-maps at the clojure.org docssets at the clojure.org docsvectors 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}。

答案 2 :(得分:1)

正如其他人所指出的那样,你使用的是的向量,而不是地图。

将一个集合作为函数调用将返回该参数,如果它在集合中,否则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很慢 - 它按元素告诉sequence元素。

顺便说一句,通过使用集合的 vector ,您将自己与标有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}]