clojure 以编程方式命名空间映射键
clojure programmatically namespace map keys
我最近学习了 clojure 中的 namespaced maps
。
非常方便,我想知道以编程方式命名地图的惯用方式是什么?还有其他我不知道的语法吗?
;; works fine
(def m #:prefix{:a 1 :b 2 :c 3})
(:prefix/a m) ;; 1
;; how to programmatically prefix the map?
(def m {:a 1 :b 2 :c 3})
(prn #:prefix(:foo m)) ;; java.lang.RuntimeException: Unmatched delimiter: )
这个函数会做你想做的事:
(defn map->nsmap
[m n]
(reduce-kv (fn [acc k v]
(let [new-kw (if (and (keyword? k)
(not (qualified-keyword? k)))
(keyword (str n) (name k))
k) ]
(assoc acc new-kw v)))
{} m))
你可以给它一个实际的命名空间对象:
(map->nsmap {:a 1 :b 2} *ns*)
=> #:user{:a 1, :b 2}
(map->nsmap {:a 1 :b 2} (create-ns 'my.new.ns))
=> #:my.new.ns{:a 1, :b 2}
或者给它一个命名空间名称的字符串:
(map->nsmap {:a 1 :b 2} "namespaces.are.great")
=> #:namespaces.are.great{:a 1, :b 2}
它只改变非限定关键字的键,这与 #:
宏的行为相匹配:
(map->nsmap {:a 1, :foo/b 2, "dontalterme" 3, 4 42} "new-ns")
=> {:new-ns/a 1, :foo/b 2, "dontalterme" 3, 4 42}
这是受 https://clojuredocs.org/clojure.walk/postwalk#example-542692d7c026201cdc327122
启发的另一个示例
(defn map->nsmap
"Apply the string n to the supplied structure m as a namespace."
[m n]
(clojure.walk/postwalk
(fn [x]
(if (keyword? x)
(keyword n (name x))
x))
m))
示例:
(map->nsmap {:my-ns/a 1 :my-ns/b 2 :my-ns/c 3} "your-ns")
=> #:your-ns{:a 1, :b 2, :c 3}
我最近学习了 clojure 中的 namespaced maps
。
非常方便,我想知道以编程方式命名地图的惯用方式是什么?还有其他我不知道的语法吗?
;; works fine
(def m #:prefix{:a 1 :b 2 :c 3})
(:prefix/a m) ;; 1
;; how to programmatically prefix the map?
(def m {:a 1 :b 2 :c 3})
(prn #:prefix(:foo m)) ;; java.lang.RuntimeException: Unmatched delimiter: )
这个函数会做你想做的事:
(defn map->nsmap
[m n]
(reduce-kv (fn [acc k v]
(let [new-kw (if (and (keyword? k)
(not (qualified-keyword? k)))
(keyword (str n) (name k))
k) ]
(assoc acc new-kw v)))
{} m))
你可以给它一个实际的命名空间对象:
(map->nsmap {:a 1 :b 2} *ns*)
=> #:user{:a 1, :b 2}
(map->nsmap {:a 1 :b 2} (create-ns 'my.new.ns))
=> #:my.new.ns{:a 1, :b 2}
或者给它一个命名空间名称的字符串:
(map->nsmap {:a 1 :b 2} "namespaces.are.great")
=> #:namespaces.are.great{:a 1, :b 2}
它只改变非限定关键字的键,这与 #:
宏的行为相匹配:
(map->nsmap {:a 1, :foo/b 2, "dontalterme" 3, 4 42} "new-ns")
=> {:new-ns/a 1, :foo/b 2, "dontalterme" 3, 4 42}
这是受 https://clojuredocs.org/clojure.walk/postwalk#example-542692d7c026201cdc327122
启发的另一个示例(defn map->nsmap
"Apply the string n to the supplied structure m as a namespace."
[m n]
(clojure.walk/postwalk
(fn [x]
(if (keyword? x)
(keyword n (name x))
x))
m))
示例:
(map->nsmap {:my-ns/a 1 :my-ns/b 2 :my-ns/c 3} "your-ns")
=> #:your-ns{:a 1, :b 2, :c 3}