如何在Clojure中从map
创建var
?
例如,如果其中一个var
名为' var',则如下所示:
(def var "I am a var")
然后,想要将其转换为以下内容:
{:var "I am a var"}
如何实现这一目标?
顺便说一句,要明确:
我希望来自f
的{{1}}其中' f'将(f var)
转换为var
。
答案 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])))