在 Clojure 中从 var 创建地图

Creating a map from a var in Clojure

如何在 Clojure 中从 var 创建 map

比如有一个叫'var'的var,如下:

(def var "I am a var")

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

{:var "I am a var"}

如何做到这一点?

顺便说一下,澄清一下: 我想要 (f var) 中的 f,其中 'f' 将 var 转换为 {:var "I am a var"}

如果您想创建一个从变量名称到它的值的映射,您可以创建一个宏:

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

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

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

(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 table:

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

仅供参考,此宏可以采用可选参数来构建映射。

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