Skip to content

Instantly share code, notes, and snippets.

@dnaeon
Last active February 17, 2019 23:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dnaeon/5e4f02a18a6f5e48bdb5925a60c48be8 to your computer and use it in GitHub Desktop.
Save dnaeon/5e4f02a18a6f5e48bdb5925a60c48be8 to your computer and use it in GitHub Desktop.
clojure-make-nested-map
;;
;; Making a deeply nested map by following parent-child relations between items
;;
(defn make-items [n]
(concat [{:id 0 :name "item-root"}]
(for [x (range 1 n)] {:id x :parent (dec x) :item (format "item-%d" x)})))
(defn item-children [item coll]
(if-let [children (-> (filter #(= (:parent %) (:id item)) coll) seq)]
(map #(assoc item :children (item-children % coll)) children)
item))
@dnaeon
Copy link
Author

dnaeon commented May 8, 2018

Example with just a few items.

user=> (require '[clojure.pprint :refer [pprint]])
nil
user=> (def items (make-items 5))
#'user/items
user=> (pprint items)
({:id 0, :name "item-root"}
 {:id 1, :parent 0, :item "item-1"}
 {:id 2, :parent 1, :item "item-2"}
 {:id 3, :parent 2, :item "item-3"}
 {:id 4, :parent 3, :item "item-4"})
nil
user=> (def root (-> (filter #(= (:name %) "item-root") items) first))
#'user/root
user=> root
{:id 0, :name "item-root"}
user=> (pprint (item-children root items))
({:id 0,
  :name "item-root",
  :children
  ({:id 1,
    :parent 0,
    :item "item-1",
    :children
    ({:id 2,
      :parent 1,
      :item "item-2",
      :children
      ({:id 3,
        :parent 2,
        :item "item-3",
        :children {:id 4, :parent 3, :item "item-4"}})})})})
nil

Now with more items.

user=> (def items (make-items 500))
#'user/items
user=> (def root (-> (filter #(= (:name %) "item-root") items) first))
#'user/root
user=> (item-children root items)
StackOverflowError   clojure.lang.PersistentHashMap$BitmapIndexedNode.ensureEditable (PersistentHashMap.java:806)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment