Skip to content

Instantly share code, notes, and snippets.

@Vaguery
Last active March 3, 2017 18:09
Show Gist options
  • Save Vaguery/141b86a9b1e102a65948090841fc1fd8 to your computer and use it in GitHub Desktop.
Save Vaguery/141b86a9b1e102a65948090841fc1fd8 to your computer and use it in GitHub Desktop.
Learning to use Specter 1.0 paths to edit trees
(ns specter-tests.core-test
(:use midje.sweet)
(:use [specter-tests.core]
[com.rpl.specter]))
(fact "I can run Midje tests in proto-REPL"
(+ 1 2) => 3)
(def deep-tree
[1 [2 3] [4 [ ] 5 [6 [7] 8] 9 [[[10 11] 12] 13]]]
)
(facts "about tree-modification in Specter"
(fact "I can use a walker to visit nodes of a tree"
(into [] (traverse (walker integer?) deep-tree)) =>
[1 2 3 4 5 6 7 8 9 10 11 12 13]
)
(fact "I can modify specified nodes of a tree in place"
(transform
[(putval 111) (walker #(and (integer? %) (even? %)))]
*
deep-tree) =>
[1 [222 3] [444 [] 5 [666 [7] 888] 9 [[[1110 11] 1332] 13]]]
)
(fact "I can replace randomly-specified nodes of a tree"
(transform
[(walker #(and (integer? %) (< (rand) 0.3)))]
(constantly 99)
deep-tree) => [99 [2 3] [99 [] 5 [6 [99] 8] 9 [[[99 11] 12] 99]]]
;;;;;;; 1 2 3 4 5 6 7 8 9 10 11 12 13
(provided (rand) =streams=> (cycle [0.1 0.9 0.9]))
)
)
;; this is a solution for replacing a random item in a tree, due to Nathan Marz
;; compose the tree-walking path manually? Not using the `walker` navigator is unexpected
(def TREE-VALUES
(recursive-path [] p
(if-path vector?
[ALL p]
STAY)))
(defn mutate-one-value
[changeable-values]
(assoc
changeable-values ;; a flat collection, here
(rand-int (count changeable-values)) ;; index of an item in the collection
1111)) ;; new value assigned to that index
(fact "trying Marz's solution"
(transform
(subselect TREE-VALUES) ;; gather all the values currently selected by TREE-VALUES
mutate-one-value
deep-tree) => [1 [2 3] [4 [] 1111 [6 [7] 8] 9 [[[10 11] 12] 13]]]
(provided (rand-int 13) => 4) ;; the "random item" will always be item #4
)
@Vaguery
Copy link
Author

Vaguery commented Mar 2, 2017

Note: I'm using midje to run tests here

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