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