假设我有一个如下所示的地图列表:
(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
,但不包含我过滤的密钥。过滤此地图的最佳方式是什么,不包括与过滤后的模式完全匹配的条目?
答案 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。