假设我有m
这样的地图{"good1" 1, "bad1" 1, "good2" 2, "bad2" 2}
,并且我想根据地图键上的某些谓词删除条目,其中一种方法是:< / p>
(defn dissoc-by [f m] (->> m (filter (complement f)) (into {})))
(dissoc-by #(.contains (first %1) "bad") m)
=> {"good1" 1, "good2" 2}
在clojure中有没有更惯用的方法呢?
答案 0 :(得分:6)
鉴于
(def data {"good1" 1, "bad1" 1, "good2" 2, "bad2" 2})
定义
(defn remove-keys [pred m]
(apply dissoc m (filter pred (keys m))))
然后
(remove-keys #(string/includes? % "bad") data)
=> {"good1" 1, "good2" 2}
类似的函数在/ The Clojure Cookbook中定义。
答案 1 :(得分:4)
这是一种非常正常的方法,只需要一次修正,即地图中的序列是一对序列[键值]而不仅仅是键,所以你的过滤函数需要明确地使用键< / p>
user> (defn dissoc-by [f m]
(into {} (filter #(f (first %))) m))
#'user/dissoc-by
user> (dissoc-by #(.contains % "good") m)
{"good1" 1, "good2" 2}
如果您想了解它并且use a transducer通过消除分配用于将数据从一个步骤移动到下一个步骤的中间序列,可以提高此功能的效率。
into
Worksheets(2).Range(Cells(finderA.Row, rng2.Column), Cells(finderA.Row, rng2.Columns.Count + rng2.Column - 1)).Copy finalWS.Cells(rowCounter, rng1.Columns.Count + 2)
采用一个可选的中间参数,一个传感器函数,可以在数据被集中到集合中时对其进行过滤或转换。
答案 2 :(得分:0)
以下是完全符合您需求的代码:
(def data {"good1" 1, "bad1" 1, "good2" 2, "bad2" 2})
(into (empty data)
(filter (fn [[k v]] (clojure.string/includes? k "good"))
data))
{"good1" 1, "good2" 2}