Skip to content

Instantly share code, notes, and snippets.

@rcampbell
Created March 4, 2010 12:33
Show Gist options
  • Save rcampbell/321662 to your computer and use it in GitHub Desktop.
Save rcampbell/321662 to your computer and use it in GitHub Desktop.
(ns match)
(defn nest [m]
"Converts a flat map with keys using underscore
nesting to proper nested maps"
(reduce (fn [m [k v]]
(let [ks (map keyword
(.split (if (keyword? k) (name k) k) "__"))]
(assoc-in m ks v))) {} m))
(defn- points [k v1 v2]
"Given a key and two values, determine how many
match points this pair is worth, adjusting for
special key weighting (todo: custom weights)"
(if (= v1 v2)
(cond (= :id k) 100
:else 1)
0))
(defn- rank
"Returns the number of matching elements
between the candidate and master"
([candidate master] (rank candidate master (vector)))
([candidate master ks]
(if (empty? master) 0
(let [e (first master) k (key e) v (val e) ks (conj ks k)]
(+ (if (map? v)
(rank candidate v ks)
(points k (get-in candidate ks) v))
(rank candidate (rest master) (vec (drop-last ks))))))))
(defn convert [query]
"Converts the query value strings to native types"
(zipmap (keys query)
(replace {"true" true
"false" false} (vals query))))
(defn best-match [query coordinates]
"Select the best matching coordinate given
the user selected query parameters"
(let [candidate (nest (convert query))]
(reduce #(if (> (rank candidate %1)
(rank candidate %2)) %1 %2)
coordinates)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment