Skip to content

Instantly share code, notes, and snippets.

@spoon16
Last active December 17, 2015 11:29
Show Gist options
  • Save spoon16/5602586 to your computer and use it in GitHub Desktop.
Save spoon16/5602586 to your computer and use it in GitHub Desktop.
;; Anything you type in here will be executed
;; immediately with the results shown on the
;; right.
;; Anything you type in here will be executed
;; immediately with the results shown on the
;; right.
(defn- flatten-item
([item]
(flatten-item item nil nil))
([item prefix incomplete]
(let [conj-prefix (partial conj (or prefix []))]
(if-let [attribute (first item)]
(let [attr-key (first attribute)
attr-value (second attribute)]
(if (map? attr-value)
(recur attr-value (conj-prefix attr-key) (conj incomplete [(rest item) prefix]))
(cons [(conj-prefix attr-key) attr-value]
(lazy-seq (flatten-item (rest item) prefix incomplete)))))
(when-let [parent (first incomplete)]
(let [parent-item (first parent)
parent-prefix (second parent)]
(recur parent-item parent-prefix (rest incomplete))))))))
(defn- attribute-key
[key]
(clojure.string/join "::" (map name key)))
(defn- attribute
[attribute]
(let [k (first attribute)
v (second attribute)]
[(attribute-key k) v]))
(into {} (map attribute (flatten-item {:user {:id "@"} :id 123 :address {:city "san francisco" :street { :number 1 :name "villa st"}}})))
;; => {"user::id" "@", "id" 123, "address::city" "san francisco", "address::street::number" 1, "address::street::name" "villa st"}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment