Created
November 21, 2013 20:56
-
-
Save jgrodziski/7589471 to your computer and use it in GitHub Desktop.
The source code of the Clojure User Group Paris talk about zipper data structure (nov 2013). Enjoy !
Slides are here : https://speakerdeck.com/jgrodziski/clojure-zipper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns zipper.core | |
(require [clojure.zip :as z])) | |
(def my-tree ["0" ["1A" "1B" "1C" | |
["2A" "2B" "2C" | |
["3A" "3B" "3C"]] | |
["2D" "2E" "2F" | |
["3D" "3E"]] | |
"1D" "1E" "1F"]]) | |
;;creation | |
(def zip (z/vector-zip my-tree)) | |
;;walking the tree to get 2A : down right down | |
(-> zip | |
z/down;;now at "0" | |
z/right;;now on first branch (this is a vector) | |
z/down;;now on 1A | |
z/right;now on 1B | |
z/right;;now on 1C | |
z/right;;now on 2nd level branch (this is a vector) | |
z/down;;now on 2A | |
z/node;;return the node value | |
) | |
;;=> "2A" | |
;;editing the tree to concatenate λ with "2A" node | |
;;achtung! return the current loc (need to (root) to get back to the | |
;;root node (achtung not a loc!) | |
(z/edit (-> zip z/down z/right z/down z/right z/right z/right z/down) (partial str "λ")) | |
(z/root (z/edit (-> zip z/down z/right z/down z/right z/right z/right z/down) (partial str "λ"))) | |
;;=> "λ2A" | |
;;your own walk | |
(defn my-walk [root-loc f] | |
(loop [loc root-loc] | |
(if (z/end? loc) | |
(z/root loc) | |
(do | |
(f (z/node loc)) | |
(recur (z/next loc)))))) | |
;;another way (mundane recursion call) to concatenate λ with "2A" node with indexes | |
(update-in my-tree [1 3 0] (partial str "λ")) | |
;;=> ["0" ["1A" "1B" "1C" ["λ2A" "2B" "2C" ["3A" "3B" "3C"]] ["2D" "2E" "2F" ["3D" "3E"]] "1D" "1E" "1F"]] | |
(defn generate-v-of-v | |
([depth nodes-nbr] (generate-v-of-v depth nodes-nbr (partial rand-int 100) nil)) | |
([depth nodes-nbr make-node parent] | |
(let [root [] | |
odd (max 3 (+ (/ nodes-nbr depth) 2))] | |
(loop [loc root | |
d 1 | |
n nodes-nbr] | |
(let [direction (rand-int odd) | |
down? (and (= 1 direction) (<= d depth)) | |
right? (not down?)] | |
(cond (<= n 0) loc | |
down? (let [branch (generate-v-of-v (inc d) n make-node loc)] | |
(recur (conj loc branch) (inc d) (- n (count branch)))) | |
right? (recur (conj loc (make-node)) d (dec n)) | |
)))))) | |
(def apps-dir (clojure.java.io/file "/Applications")) | |
(def tmp-dir (clojure.java.io/file "/tmp")) | |
(defn file-zip [dir] | |
(z/zipper (fn [f] (.isDirectory f)) | |
(fn [f] (.listFiles f)) | |
(fn [dir files] | |
(doseq [file files] | |
(if (string? file) | |
(.createNewFile (java.io.File. dir file))))) | |
dir)) | |
(def apps (file-zip apps-dir)) | |
(def tmp (file-zip tmp-dir)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment