简体   繁体   English

clojure过滤器按键映射

[英]clojure filter map by keys

I'm following this example: http://groups.google.com/group/clojure/browse_thread/thread/99b3d792b1d34b56 我正在关注此示例: 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? 是不是(某些......)每次都会返回第一个匹配值“x”? I'm a total noob at clojure and just trying to learn. 我是一个完全没人参加clojure并且只是想学习。

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. 因此,你的匿名函数试图评估(some [:a "x"] [:a :b]) ,这显然不起作用。

The ideomatic solution is to use select-keys as mentioned in another answer. 理想的解决方案是使用另一个答案中提到的select-keys

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

Would do the same using filter and some (but uglier and slower). 使用filtersome (但更丑陋和更慢)会做同样的事情。

This works by filter all from m if some [:a :b] is in the set #{(key x)} (ie using a set as predicate) then return the map entry. 如果某些[:a :b]在集合#{(key x)} (即使用set作为谓词),则通过mm过滤,然后返回映射条目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM