使用可能不同的键过滤clojure中的地图列表

时间:2015-08-18 17:41:38

标签: clojure

假设我有一个如下所示的地图列表:

(def my-map '({:some-key {:another-key "val"}
  :id "123"}
 {:some-key {:another-key "val"}
  :id "456"}
 {:some-other-key {:a-different-key "val2"}
  :id "789"})

在我尝试按:another-key过滤此地图时,我尝试了这个:

(filter #(= "val" ((% :some-key) :another-key)) my-map)))

但是,这会在地图条目上抛出NullPointerException,但不包含我过滤的密钥。过滤此地图的最佳方式是什么,不包括与过滤后的模式完全匹配的条目?

1 个答案:

答案 0 :(得分:2)

如果地图密钥不在地图中,则首次查找密钥:some-key将返回nil。调用nil将导致您看到的NPE。

解决方案很简单,只需在地图中进行关键字查找,即使给定nil也可以工作:

(def my-map '({:some-key {:another-key "val"}
               :id "123"}
               {:some-key {:another-key "val"}
                :id "456"}
               {:some-other-key {:a-different-key "val2"}
                :id "789"}))

(filter #(= "val" (:another-key (% :some-key))) my-map)

您还可以使用get-in

(filter #(= "val" (get-in % [:some-key :another-key])) my-map)

如果您的列表可能包含nil项:

(filter #(= "val" (:another-key (:some-key %))) my-map)

说明:

(:k nil);; => nil
(nil :k);; => NPE
({:k 4} :k);; => 4
(:k {:k 4});; => 4
;; BTW, you can also specify the "not found" case:
(:k nil :not-there);; => :not-there

另请参阅clojure style guide