2009-07-13 3 views
3

にリスト内のマップにアクセスすると、ここでは、コードです:名前と::このコードのビットでは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 

、私は含むエントリーと呼ばれるマップを定義NUM、その後私は、リストに入れてリストの最初の(そして唯一の)要素の:nameフィールドを表示しようとします。 (または少なくとも私のコードは次のように思っています:o)

私はリストに入れる前にエントリマップから名前にアクセスできますが、リストに入るとこのエラーが出ます。私は何を言いたいのですか?

答えて

3

2つの問題があります。

最初に、解決するシンボルを含むリスト(ケース内のシンボルエントリなど)では、通常の引用符(アポストロフィ)の代わりにsyntax-quote(バックティック)を使用する必要があります。したがって、この行:

(def tempList '(entry)) 

にすべきである:

(def tempList `(entry)) 

または単に(より慣用とClojureのに使用することが容易であるベクターを使用して):

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

次に、変更をこの行

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

とe

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

またはこの:このither

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

からオフ()を取る(:name)を3行目に。 :キーワードは、引数としてマップを取ると、それがリストにnthを使用してこの場合

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

の誤差が多少混乱になり、悪いアイデア理由ですが、非常に便利である「自分自身を見上げる」機能です毎回要素を検索するために線形検索を行う必要があります。ベクターは、ここで使用する正しいコレクションタイプです。

ベクトルは値のインデックスの「マップ」です。

(:name (tempList 0)) 

または::

(get (get tempList 0) :name) 

または:あなたの代わりに、リストのベクトルを使用する場合は、あなたがこれを行うことができます

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

を私はこのようなコードを記述します。

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

(def tempList (list entry)) 

(println (:name (first tempList))) 

nthを使用するよりもはるかに使いやすく、キーワードはマップ内で自分自身を見るための関数として機能することができます。同等の別のアプローチは、関数を構成してリストに適用することです。

((comp println :name first) tempList)