clojure过滤器按键映射

时间:2011-08-26 16:01:09

标签: clojure

我正在关注此示例:http://groups.google.com/group/clojure/browse_thread/thread/99b3d792b1d34b56

(见最后的回复)

这是我得到的神秘错误:

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=>

此外,我不明白为什么这甚至会起作用。是不是(某些......)每次都会返回第一个匹配值“x”?我是一个完全没人参加clojure并且只是想学习。

请赐教。

3 个答案:

答案 0 :(得分:28)

我想我只需要阅读更多文档:

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

虽然我仍然不确定我发现的例子意图是什么......

答案 1 :(得分:8)

如果你在地图上“迭代”,你将获得键值对而不是键。例如,

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

因此,您的匿名函数会尝试评估显然不起作用的(some [:a "x"] [:a :b])

意识形态的解决方案是使用另一个答案中提到的select-keys

答案 2 :(得分:1)

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

使用filtersome会做同样的事情(但更丑陋和更慢)。

如果某个m位于集合[:a :b]中(即使用集合作为谓词),则可以从#{(key x)}过滤所有内容,然后返回地图条目。