在Clojure中访问列表中的地图

时间:2009-07-13 21:15:53

标签: list map clojure

以下是代码:

(def entry {:name tempName :num tempNum})

(def tempList '(entry))

(println (get (nth tempList 0) (:name)))

Exception in thread "main" java.lang.IllegalArgumentException: Wrong number of args passed to keyword: :name

在这段代码中,我定义了一个名为entry的映射,其中包含:name和a:num,然后我把它放在一个列表中,然后我尝试打印:name的第一个(也是唯一的)元素的:name字段列表。 (或者至少这是我认为我的代码所做的事情:o)

我可以在将其放入列表之前从条目映射中访问名称,但是一旦它在列表中,我就会收到此错误。我应该给予什么?

4 个答案:

答案 0 :(得分:3)

有两个问题。

首先,对于包含要解析的符号的列表(如您的情况中的符号条目),您必须使用syntax-quote(反引号)而不是常规引号(撇号);所以这一行:

(def tempList '(entry))

应该是:

(def tempList `(entry))

或者只是(使用矢量,这在Clojure中更惯用且更容易使用):

(def tempList [entry]) ; no quoting needed for vectors

然后,更改此行

(println (get (nth tempList 0) (:name)))

要么:

(println (get (nth tempList 0) :name))

或者这个:

(println (:name (nth tempList 0)))

答案 1 :(得分:2)

在列表中使用nth是一个坏主意,因为它必须每次都进行线性搜索以检索元素。 Vector是这里使用的正确集合类型。

向量是指数与值的“映射”。如果您使用向量而不是列表,则可以执行此操作:

(:name (tempList 0))

或者:

(get (get tempList 0) :name)

或者:

(get-in tempList [0 :name]))

答案 2 :(得分:1)

从第3行的(:name)取消()。 :关键字是将地图作为参数并“自我查找”的功能,虽然它在这种情况下使错误更加混乱,但却非常方便

(get (nth '({:name "asdf"}) 0) :name))

答案 3 :(得分:1)

我会写这样的代码:

(def entry {:name tempName :num tempNum})

(def tempList (list entry))

(println (:name (first tempList)))

请注意,first比使用nth更加整洁,关键字可以充当在地图中查找自己的功能。另一种等效方法是组合函数并将它们应用于列表:

((comp println :name first) tempList)