2016-03-23 5 views
1

Clojureのvarからmapを作成するにはどうすればよいですか?Clojureのvarからマップを作成する

(def var "I am a var") 

をそして、一つは次のように変換したい:1が持っている場合たとえば

は、 'VAR' と呼ばvar、次のように

{:var "I am a var"} 

する方法1が達成んそれ?ところで

、ちょうど明確にする: 私は、「F」は{:var "I am a var"}からvarを変換(f var)からfをしたいです。

+0

本当にClojureの 'var'が必要ですか?あるいは単にマップにkvペアを追加しようとしていますか? http://swannodette.github.io/2014/12/17/whats-in-a-var/ – jmargolisvt

+0

@jmargolisvtはKVペアを追加することもできます。しかし、私はキーがvarの名前と同じ名前であることを望みます。 –

+5

その使用例を含めてください。値を持つvarを作成するかどうかは、var名をキーワードとしたマップと、ある式の値(例:リテラルまたはs式)とのあいだにあいまいです。どうか明らかにしてください。 –

答えて

2

あなたは、その値にVAR名からマップを作成したい場合は、マクロを作成することができます。varのメタデータを使用している場合

(defmacro to-map [sym] 
    `{(keyword '~sym) ~sym}) 

(to-map var) 
=> {:var "I am a var"} 
+0

それが答えかどうか分かりません。私はfを(f var)から 'f'がvarを{:var var}に変換する場所を求めます。 –

+0

@IanChuTe - 更新を参照してください。 – Lee

+2

は引用符なしでコンパイル時にそれを行うには十分ではありませんか? '(defmacro to map [sym] {(keyword sym)sym})' – leetwinski

0

多分あなたが行うことができます:REPLで

(defn process-var [param] 
    {(-> param meta :name keyword) 
    @param}) 

user> (def x "fourty two") 
#'user/x 

user> (process-var #'x) 
{:x "fourty two"} 

user> (def y 1001) 
#'user/y 

user> (map (comp process-var (ns-interns *ns*)) '(x y)) 
({:x "fourty two"} {:y 1001}) 

user> (map (comp process-var (ns-interns *ns*)) '(x y process-var)) 
({:x "fourty two"} {:y 1001} {:process-var #function[user/process-var]}) 

も名前空間のシンボルテーブルからVaRのストレートを取ることができます。

(defn by-name 
    ([name-symbol] (by-name name-symbol *ns*)) 
    ([name-symbol ns] 
    {(keyword name-symbol) 
    (deref (ns-resolve ns name-symbol))})) 

user> (by-name 'x) 
{:x "fourty two"} 

user> (by-name 'map 'clojure.core) 
{:map #function[clojure.core/map]} 

user> (by-name '*clojure-version* 'clojure.core) 
{:*clojure-version* {:major 1, :minor 8, :incremental 0, :qualifier nil}} 
0

FYIでは、このマクロはオプションの引数をとってマップを作成できます。

(defmacro to-map [& vs] 
    "foo = 1, bar = 2. (to-map foo bar) ==> {:foo 1 :bar 2}" 
    `(let [ks# (map keyword '~vs)] 
    (zipmap ks# [[email protected]]))) 
関連する問題