When given the following set of vecs

#{[1 2 3]   [9 8 3]   [1 2]   [1]   [1 0 3 4]   [1 2 3 4 5]}

find the closest match to [1 2 3]

(defn closest-match
  "Searches the haystack vecs for the closest match to the needle vec"
  [#^IPersistentVector needle #^IPersistentVector haystack]
  (second
   (last
    (apply sorted-map
           (apply concat
                  (map (fn [candidate]
                         [(reduce + (map #(if (= %1 %2) 1 0) needle candidate)) 
candidate])
                       haystack))))))

I wanted a three-step process:

1) Count the number of matching elements for each candidate
*2) When counts are equal, select the shortest candidate, discarding
the rest  <-- help!
3) Return the candidate with the highest count

Stepping through the execution,

                  (map (fn [candidate]
                         [(reduce + (map #(if (= %1 %2) 1 0) needle candidate)) 
candidate])
                       haystack)
                  ; returns ([1 [1]] [2 [1 0 3 4]] [3 [1 2 3]] [3 [1 2 3 4 5]] 
[2 [1
2]] [1 [9 8 3]]), a vec matching counts to candidates

           (apply concat ...
           ; returns (1 [1] 2 [1 0 3 4] 3 [1 2 3] 3 [1 2 3 4 5] 2 [1
2] 1 [9 8 3]) for consumption by "apply assoc {}" or "apply
sorted-map"

    (apply sorted-map
    ; returns {1 [9 8 3], 2 [1 2], 3 [1 2 3 4 5]} <-- here is where
things get screwed up

When I apply the sorted-map, it will just take the last candidate for
matching counts. In other words, given (3 [1 2 3] 3 [1 2 3 4 5]) it
will return [1 2 3 4 5]. I'd instead like it to take the shorted
candidate, which in this case is [1 2 3].

What are some ways I could simplify/improve this function? How might I
implement my missing 2nd step so that it correctly picks the closest
match?

Rob

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to