简体   繁体   English

根据谓词clojure从地图中删除键

[英]Remove key from map based on predicate clojure

Say I have a map m like {"good1" 1, "bad1" 1, "good2" 2, "bad2" 2} , and I'd like to remove entries based on some predicate over the keys of the map, one way to do this would be: 说我有一个地图m{"good1" 1, "bad1" 1, "good2" 2, "bad2" 2}我想要基于一些谓词在地图的键来删除条目,单程这样做将是:

(defn dissoc-by [f m] (->> m (filter (complement f)) (into {})))
(dissoc-by #(.contains (first %1) "bad") m)
 => {"good1" 1, "good2" 2}

Is there a more idiomatic way of doing this in clojure? 在clojure中有更多惯用的方法吗?

Given 特定

(def data {"good1" 1, "bad1" 1, "good2" 2, "bad2" 2})

define 限定

(defn remove-keys [pred m]
  (apply dissoc m (filter pred (keys m))))

then 然后

(remove-keys #(string/includes? % "bad") data)
=> {"good1" 1, "good2" 2}

Similar functions are defined in/at The Clojure Cookbook . 类似的功能在Clojure Cookbook中定义。

This is a very normal way of going about it, with the one correction that a sequence from a map is a sequence of pairs [key value] rather than just the keys, so your filter function needs to use the key explicitly 这是一种非常正常的方法,只需要一次修正,即地图中的序列是一对序列[键值]而不仅仅是键,所以你的过滤函数需要明确地使用键

user> (defn dissoc-by [f m] (->> m (filter #(f (first %))) (into {})))
#'user/dissoc-by
user> (dissoc-by #(.contains % "good") m)
{"good1" 1, "good2" 2}

If you would like to get fancy about it and use a transducer this function can be made more efficient by eliminating the intermediate sequences that are allocated to move data from one step to the next. 如果您想了解并使用传感器,可以通过消除分配用于将数据从一个步骤移动到下一个步骤的中间序列来提高此功能的效率。

user> (defn dissoc-by [f m]
        (into {} (filter #(f (first %))) m))
#'user/dissoc-by
user> (dissoc-by #(.contains % "good") m)
{"good1" 1, "good2" 2}

into takes an optional middle argument, a transducer function, that can filter or transform the data as it is pored into the collection. into有一个可选的中间参数,换能器的功能,即可以过滤或因为它倾入收集转换数据。

Here is the code that does exactly what you need: 以下是完全符合您需求的代码:

(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}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM