【问题标题】:Filter a collection by multiple attributes provided with a map按地图提供的多个属性过滤集合
【发布时间】:2016-01-08 05:53:15
【问题描述】:

我有一个要过滤的集合。过滤器使用映射完成,其中键是集合项中的属性,值是集合项应匹配的值。示例:

(let [filters {:name "test"
               :type "new"}
      collection [{:name "testable"  :type "old"}
                  {:name "shoudwork" :type "new"}
                  {:name "testable"  :type "new"}]])

现在,我已经构建了我的过滤器函数,只接受一个属性和值。我想将其扩展为实际上能够采用过滤器hashmap

这是我当前的过滤器的样子:

(filter #(re-find (re-pattern "test") (string/lower-case (% :name))) collection)

换句话说,我希望filter 不采用"test" 硬编码,但它应该是来自filters let 绑定的值,并且(% :name) 不被硬编码为:name,但是是来自filters的钥匙让绑定。

【问题讨论】:

    标签: filter clojure


    【解决方案1】:

    创建一个函数,返回单个[key expected-value]的过滤函数:

    (defn regex-value [[k expected-rex]]
      (fn [c] (re-find (re-pattern expected-rex) 
                       (clojure.string/lower-case (get c k)))))
    

    创建一个将创建复合过滤条件的函数:

    (defn build-filter [filters]
      (apply every-pred (map regex-value filters)))
    

    使用它:

    (let [filters {:name "test"
                   :type "new"}
          collection [{:name "testable"  :type "old"}
                      {:name "shoudwork" :type "new"}
                      {:name "testable"  :type "new"}]]
      (filter (build-filter filters) collection))
    

    【讨论】:

    • 我真的很喜欢这个,因为它使用了every-pred。我尝试将其合并到自己的解决方案中,但失败了。
    【解决方案2】:

    您也可以使用传感器:

    ;; first you create a filtering step factory for transduction:
    (defn make-filter [[k v]]
      (filter #(re-find (re-pattern v)
                        (clojure.string/lower-case (k %)))))
    
    ;; and then transform the collection:
    (let [filters {:name "test"
                   :type "new"}
          collection [{:name "testable"  :type "old"}
                      {:name "shoudwork" :type "new"}
                      {:name "testable"  :type "new"}]]
      (sequence (reduce comp (map make-filter filters)) collection))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-09
      • 1970-01-01
      • 1970-01-01
      • 2014-09-22
      相关资源
      最近更新 更多