【问题标题】:Filtering a list of maps in clojure with potentially different keys使用可能不同的键过滤 clojure 中的映射列表
【发布时间】:2015-08-18 17:41:38
【问题描述】:

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

(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。过滤此映射的最佳方法是什么,排除与过滤模式不完全匹配的条目?

【问题讨论】:

    标签: clojure


    【解决方案1】:

    如果映射键不在映射中,您对键 :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

    【讨论】:

      猜你喜欢
      • 2011-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-02
      • 1970-01-01
      • 2023-03-23
      • 2020-04-05
      • 2021-08-13
      相关资源
      最近更新 更多