Skip to content

Instantly share code, notes, and snippets.

@favila
Created June 23, 2017 09:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save favila/36a159b644965f61493289246769e33f to your computer and use it in GitHub Desktop.
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)
(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