簡體   English   中英

通過Clojure中的鍵值過濾地圖列表的簡便方法

[英]Easy way to filter list of maps by values of keys in Clojure

我在Clojure中找不到內置功能,無法通過鍵值過濾地圖列表。 例如,我們有以下列表:

user=> (def animals (list {:name "Charlie" :weight 350 :specie :elephant}
                          {:name "Vasya" :weight 250 :specie :bear}
                          {:name "John" :weight 200 :specie :elephant}
                          {:name "Monk" :weight 200 :specie :monkey}))
#'user/animals

例如,我想選擇所有帶有值:elephant:specie 我怎樣才能做到這一點? 我發現的最好方法是:

user=> (defn filter-data [data m]
         (let [k (keys m) v (vals m)]
           (filter #(= (map % k) v) data)))
#'user/filter-data

user=> (clojure.pprint/print-table (filter-data animals {:specie :elephant}))

|   :name | :weight |   :specie |
|---------+---------+-----------|
| Charlie |     350 | :elephant |
|    John |     200 | :elephant |
nil

有更好的方法嗎?

使用過濾器可以輕松實現

(clojure.pprint/print-table 
  (filter #(= (:specie %) :elephant) animals))

您始終可以將過濾器包裝在函數中以獲取不同的“語法”,例如:

(defn cool-filter [[k v] l]
  (filter #(= (k %) v) l))

(clojure.pprint/print-table 
  (cool-filter [:specie :elephant] animals))

您還可以使用函數組合:

(filter (comp (partial = :elephant) :specie) animals)

要么...

(filter (comp #{:elephant} :specie) animals)

雖然filter解決方案顯然是最簡單的方法,但是我想添加一個替代方案,以防您需要查找多個物種:

(def grouped-animals (group-by :specie animals))
(:elephant grouped-animals)
; [{:name "Charlie", :weight 350, :specie :elephant} {:name "John", :weight 200, :specie :elephant}]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM