Skip to content

Commit

Permalink
Add prefix-lookup
Browse files Browse the repository at this point in the history
  • Loading branch information
amalloy committed Jun 6, 2012
1 parent 1bab9df commit 29e08a1
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 2 deletions.
19 changes: 17 additions & 2 deletions src/useful/experimental.clj
@@ -1,9 +1,9 @@
(ns useful.experimental
(:use [useful.utils :only [split-vec]]
[useful.seq :only [alternates]]
[useful.seq :only [alternates find-first]]
[useful.map :only [keyed]]
[clojure.tools.macro :only [name-with-attributes]]
[useful.fn :only [any as-fn]]))
[useful.fn :only [any as-fn knit]]))

(defn comp-partial
"A version of comp that \"rescues\" the first N args, passing them to every composed function
Expand Down Expand Up @@ -234,3 +234,18 @@
[m & ks]
(-> (apply dissoc m ks)
(vary-meta merge (select-keys m ks))))

(defn prefix-lookup
"Takes a map whose keys are names, and returns a function that does fast prefix
matching on its input against the names in the original map, returning the
first value whose key is a prefix.
If order is important (eg because your prefixes overlap, or you want to test
common prefixes first for performance), you can pass a sequence of pairs
instead of a map."
[prefix-map]
(let [name-pairs (map (knit name identity) prefix-map)]
(fn [^String s]
(when-let [pair (find-first #(.startsWith s (first %))
name-pairs)]
(second pair)))))
12 changes: 12 additions & 0 deletions test/useful/experimental_test.clj
Expand Up @@ -160,3 +160,15 @@
(let [m (lift-meta {:a 1 :b 2} :a)]
(is (= {:b 2} m))
(is (= {:a 1} (meta m)))))

(deftest prefix-lookup-test
(let [lookup (prefix-lookup [["a" :apple]
["person" :person]
[:p :pineapple]
["abbrev" :abbreviation]])]
(are [in out] (= out (lookup in))
"apropos" :apple
"persona" :person
"pursues" :pineapple ;; keywords should work
"abbrev." :apple ;; should test in order, and short-circuit
)))

0 comments on commit 29e08a1

Please sign in to comment.