从Clojure中的var创建地图

时间:2016-03-23 14:47:28

标签: dictionary clojure var

如何在Clojure中从map创建var

例如,如果其中一个var名为' var',则如下所示:

(def var "I am a var")

然后,想要将其转换为以下内容:

{:var "I am a var"}

如何实现这一目标?

顺便说一句,要明确: 我希望来自f的{​​{1}}其中' f'将(f var)转换为var

3 个答案:

答案 0 :(得分:2)

如果要创建从var名称到其值的映射,可以创建一个宏:

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

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

答案 1 :(得分:0)

如果使用var的元数据,也许你可以这样做:

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

在repl中:

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}}

答案 2 :(得分:0)

仅供参考,此宏可以使用可选的参数来构建地图。

(defmacro to-map [& vs]
  "foo = 1, bar = 2.  (to-map foo bar) ==> {:foo 1 :bar 2}"
  `(let [ks# (map keyword '~vs)]
     (zipmap ks# [~@vs])))