开发者

clojure filter map by keys

开发者 https://www.devze.com 2023-03-31 05:19 出处:网络
I\'m following this exa开发者_开发百科mple: http://groups.google.com/group/clojure/browse_thread/thread/99b3d792b1d34b56

I'm following this exa开发者_开发百科mple: http://groups.google.com/group/clojure/browse_thread/thread/99b3d792b1d34b56

(see the last reply)

And this is the cryptic error that 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=>

Also I don't understand why this would even work. Isn't (some ...) going to return the first matching value, "x", every time? I'm a total noob at clojure and just trying to learn.

Please enlighten me.


I guess 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...


If you "iterate" over a map, you'll get key-value pairs rather than keys. For instance,

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

Thus your anonymous function tries to evaluate (some [:a "x"] [:a :b]) which clearly does not work.

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


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

Would do the same using filter and some (but uglier and slower).

This works by filter all from m if some [:a :b] is in the set #{(key x)} (i.e. using a set as predicate) then return the map entry.

0

精彩评论

暂无评论...
验证码 换一张
取 消