在Clojure中是否有创建哈希映射的简短形式?
是否有一个简短的表单/宏允许我这样做在Clojure中是否有创建哈希映射的简短形式?,clojure,Clojure,是否有一个简短的表单/宏允许我这样做 (defn f [a b c] {a b c}) 而不是 (defn f [a b c] {:a a :b b :c c}) 这显示了步骤。删除println以供实际使用: (ns clj.core (:gen-class)) (defmacro hasher [& args] (let [keywords (map keyword args) values args k
(defn f [a b c]
{a b c})
而不是
(defn f [a b c]
{:a a :b b :c c})
这显示了步骤。删除println以供实际使用:
(ns clj.core
(:gen-class))
(defmacro hasher [& args]
(let [keywords (map keyword args)
values args
keyvals-list (interleave keywords values)
]
(println "keywords " keywords)
(println "values " values)
(println "keyvals-list " keyvals-list)
`(hash-map ~@keyvals-list)
)
)
(def a 1)
(def b 2)
(println \newline "result: " (hasher a b))
> lein run
keywords (:a :b)
values (a b)
keyvals-list (:a a :b b)
result: {:b 2, :a 1}
用法:
(def a 42)
(def b :foo)
(as-map a b)
;;-> {:a 42 :b :foo}
(def a 42)
(def b :foo)
(as-map example/a foo-of/b)
;;-> {:example/a 42 :foo-of/b :foo}
请注意,要支持名称空间的关键字,如果要使其保持简短,则必须放弃对ns别名的支持:
(defmacro as-map [& syms]
(zipmap (map keyword syms) (map (comp symbol name) syms)))
用法:
(def a 42)
(def b :foo)
(as-map a b)
;;-> {:a 42 :b :foo}
(def a 42)
(def b :foo)
(as-map example/a foo-of/b)
;;-> {:example/a 42 :foo-of/b :foo}
建议:这可能不是一个好主意,它可以为您节省一些键盘点击量,但代价是可读性、表现力和命名本地绑定的灵活性 这是我的一个老片段,我已经玩了一段时间了
(declare ^:private restructure*)
(defn ^:private restructure-1 [m [e k]]
(cond
(= :strs e) (reduce #(assoc %1 (name %2) %2) m k)
(= :keys e) (reduce #(assoc %1 (keyword (namespace %2) (name %2)) %2) m k)
:else (assoc m k (restructure* e))))
(defn ^:private restructure* [form]
(if-not (map? form)
form
(as-> {} v
(reduce restructure-1 v form)
`(hash-map ~@(mapcat identity v)))))
(defmacro restructure [form]
(restructure* form))
其思想是,它提供了clojure.core/destructure的补充,它从一种解构形式扩展到绑定,从而捕获绑定并构建数据结构
(let [x 1 y 2 z 3]
(restructure {:keys [x y z]}))
;; => {:x 1 :y 2 :z 3}
散列映射
不起作用,因为他想要映射的反结构。构造散列映射的宏很好。