Clojure Key Filter Filter

I follow this example: http://groups.google.com/group/clojure/browse_thread/thread/99b3d792b1d34b56

(see last answer)

And this is the cryptic error I get:

Clojure 1.2.1 user=> (def m {:a "x" :b "y" :c "z" :d "w"}) #'user/m user=> (filter #(some % [:a :b]) m) java.lang.IllegalArgumentException: Key must be integer (user=> 

And I don’t understand why this will even work. Wouldn't (some ...) return the first matching "x" value each time? I am a complete noob in clojure and just trying to learn.

Please enlighten me.

+8
clojure
source share
3 answers

If you "iterate over" the map, you will get key-value pairs, not keys. For example,

  user=> (map #(str %) {:a 1, :b 2, :c 3}) ("[:a 1]" "[:b 2]" "[:c 3]") 

So your anonymous function is trying to evaluate (some [:a "x"] [:a :b]) , which is obviously not working.

The ideomatic solution is to use select-keys as indicated in another answer.

+8
source share

I think I just needed to read the docs more:

 (select-keys m [:a :b]) 

Although I'm still not sure what the intention was with the example I found ...

+26
source share
 (filter (fn [x] (some #{(key x)} [:a :b])) m) 

Will do the same with filter and some (but more ugly and slow).

This works with the filter all of m , if some [:a :b] is in the set #{(key x)} (that is, using the set as a predicate), then it returns the map record.

+1
source share

All Articles