Created
June 23, 2017 09:41
-
-
Save favila/36a159b644965f61493289246769e33f to your computer and use it in GitHub Desktop.
Comparator to sort path vectors (e.g. as used with get-in, assoc-in, update-in) in depth-first order instead of breath-first (which the standard comparator does)
This file contains hidden or 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
(letfn [(cmp [^objects vec-b+maxi i a] | |
;; INVARIANT: vec-a is longer than or equal-len vec-b | |
;; INVARIANT: vec-a and vec-b are len >= 1 | |
(let [vec-b (aget vec-b+maxi 0) | |
maxi (aget vec-b+maxi 1) | |
b (nth vec-b i) | |
diff (compare a b)] | |
(if (zero? diff) | |
(if (== i maxi) | |
(reduced vec-b+maxi) | |
vec-b+maxi) | |
(reduced diff)))) | |
(finalize [x default] | |
(if (number? x) | |
x | |
default))] | |
(defn- depth-first-path-compare [vec-a vec-b] | |
(let [cva (count vec-a) | |
cvb (count vec-b)] | |
(if (>= cva cvb) | |
(-> (reduce-kv cmp | |
(doto (object-array 2) | |
(aset 0 vec-b) | |
(aset 1 ^Object (dec (count vec-b)))) | |
vec-a) | |
(finalize (if (== cva cvb) 0 1))) | |
(-> (reduce-kv cmp | |
(doto (object-array 2) | |
(aset 0 vec-a) | |
(aset 1 ^Object (dec (count vec-a)))) | |
vec-b) | |
(finalize 1) | |
(-)))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment