2013-07-27 3 views
9

Gegeben eine verschachtelte Karte mit nur Schlüsselworten wie {:foo {:bar 1 :baz [2 3] :qux {:quux 4}} :corge 5}, wie kann ich flatten-map implementieren, so dass (flatten-map {:foo {:bar 1 :baz [2 3] :qux {:quux 4}} :corge 5} "-") etwas wie {:foo-bar 1 :foo-baz [2 3] :foo-qux-quux 4 :corge 5} produziert.Abflachung einer Karte durch die Tasten

Mein bester Versuch ist:

(defn flatten-map 
    ([form separator] (flatten-map form separator nil)) 
    ([form separator prefix] 
    (if (map? form) 
    (into {} (map (fn [[k v]] 
        [(keyword (str prefix (name k))) 
        (flatten-map v separator (str prefix (name k) separator))]) 
        form)) 
    form))) 

Wie man sehen kann ich nicht flatten-map bekommen können nur die „Blätter“ zu wählen.

Antwort

11
(defn flatten-map 
    ([form separator] 
    (into {} (flatten-map form separator nil))) 
    ([form separator pre] 
    (mapcat (fn [[k v]] 
       (let [prefix (if pre (str pre separator (name k)) (name k))] 
       (if (map? v) 
        (flatten-map v separator prefix) 
        [[(keyword prefix) v]]))) 
       form))) 

wurden Sie bedingungslos neue Schlüssel/Wert-Paare zu schaffen, selbst wenn der Wert erweitert werden sollte, so wechselte ich Karte so mapcat, dass ein Ergebnis „subsumiert“ in die obersten Ebene werden könnte (diese auch erforderlich Splitting die (into {} ...) in die Top-Level-Version des Formulars, da wir eigentlich keine Karten irgendwo anders als die oberste Ebene der Ausgabe wollen).

Hier ist, wie es mit Ihrem Beispiel funktioniert:

user> (flatten-map {:foo {:bar 1 :baz [2 3] :qux {:quux 4}} :corge 5} "-") 
{:foo-bar 1, :foo-qux-quux 4, :foo-baz [2 3], :corge 5} 
+0

Perfect! Vielen Dank. –

Verwandte Themen