2017-05-01 1 views
3

Ich habe vor kurzem über namespaced maps in Clojure gelernt. Sehr praktisch, ich frage mich, was wäre die idiomatische Art der programmatischen Namespace einer Karte? Gibt es eine andere Syntax, die mir nicht bekannt ist?clojure programmatisch Namespace Map Keys

;; 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:) 

Antwort

2

Diese Funktion wird tun, was Sie wollen:

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

Sie können es Objekt einen tatsächlichen Namensraum geben:

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

Oder es eine Zeichenfolge für den Namespace-Namen geben:

(map->nsmap {:a 1 :b 2} "namespaces.are.great") 
=> #:namespaces.are.great{:a 1, :b 2} 

Und es tut s Schlüssel nicht ändern, es sei denn, sie sind bereits nicht qualifizierte Schlüsselwörter, was das gleiche Verhalten ist wie das #: Makro:

(map->nsmap {:a 1, :foo/b 2, "dontalterme" 3, 4 42} "new-ns") 
=> {:new-ns/a 1, :foo/b 2, "dontalterme" 3, 4 42} 
Verwandte Themen