Skip to content

Instantly share code, notes, and snippets.

@Conaws
Created June 15, 2016 05:26
Show Gist options
  • Save Conaws/647c942ca0c6e0ffd536463f7be6747f to your computer and use it in GitHub Desktop.
Save Conaws/647c942ca0c6e0ffd536463f7be6747f to your computer and use it in GitHub Desktop.
; In case anyone else is interested, here are a few specter functions I wrote that will
; find all the nested maps inside a composite datastructure,
; assign each of them a temporary id
; then it'll pull it apart into a list,
; and replace all references to the map with its id
(ns extract-maps
(:require [datascript.core :as d]
[com.rpl.specter :as sp
:refer [ALL LAST MAP-VALS FIRST subselect
stay-then-continue collect selected?
pred must
collect-one if-path]]
[clojure.pprint :refer [pprint]]
[clojure.string :as string])
(:use
[com.rpl.specter.macros
:only [select transform setval declarepath providepath]]))
(declarepath TOPSORT3)
(providepath TOPSORT3
(sp/cond-path
map?
(stay-then-continue
[MAP-VALS TOPSORT3])
coll?
[ALL TOPSORT3]))
(declarepath NodeWalker)
(providepath NodeWalker
(sp/cond-path
map? #(:tempid %)
coll? ALL NodeWalker))
(defn maps->ds [maps]
(->> maps
(transform [(subselect TOPSORT3 :tempid) (sp/view count)]
#(range (- %) 0))
(select TOPSORT3)
(transform [ALL MAP-VALS NodeWalker] :tempid)))
;;; so if you have
(def sampmap2
[{:a "foo"
:b "bar"
:c [{:this "other thing"
:that {:nested :map
:deeper #{{:in :we-go}}}}]}])
;;; and call
(maps->ds sampmap2)
;; you get
; ({:a "foo", :b "bar", :c [-3], :tempid -4}
; {:this "other thing", :that -2, :tempid -3}
; {:nested :map, :deeper #{-1}, :tempid -2}
; {:in :we-go, :tempid -1})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment