【问题标题】:How to remove multiple keys from a map?如何从地图中删除多个键?
【发布时间】:2012-03-31 20:03:18
【问题描述】:

我有一个从地图中删除键的函数:

(defn remove-key [key map]
  (into {}
        (remove (fn [[k v]] (#{key} k))
                map)))

(remove-key :foo {:foo 1 :bar 2 :baz 3})

如何使用多个键应用此功能?

(remove-keys [:foo :bar] {:foo 1 :bar 2 :baz 3})

我有一个使用循环...recur 的实现。在 Clojure 中是否有更惯用的方式来执行此操作?

(defn remove-keys [keys map]
  (loop [keys keys
         map map]
    (if (empty? keys)
      map
      (recur (rest keys) (remove-key (first keys) map)))))

【问题讨论】:

    标签: clojure


    【解决方案1】:

    dissoc 从地图中删除一个或多个键:

    (dissoc {:foo 1 :bar 2 :baz 3} :foo :bar)
    

    或者,如果您在集合中有键

    (apply dissoc {:foo 1 :bar 2 :baz 3} [:foo :bar])
    

    【讨论】:

    • Clojure 没有办法在函数调用中“分解”向量吗?阿拉 Python 的 *list?
    • @john2x, apply 正是这样做的。即,(apply f foo bar baz) 等价于 python 中的f(foo bar *baz)
    • 矢量形式对我不起作用。我做了以下(键的字符串):(dissoc map "foo" "bar" )
    【解决方案2】:

    您的remove-key 函数被标准库函数dissoc 覆盖。 dissoc 将一次删除多个键,但它希望直接在参数列表中而不是在列表中给出键。因此,您可以使用apply 将其“展平”。

    (apply dissoc {:foo 1, :bar 2, :baz 3} [:foo :bar])
    ==> {:baz 3}
    

    【讨论】:

      【解决方案3】:

      正如其他人所说,使用内置函数而不是自己编写。

      但是,如果这只是一个示例,并且您想知道在没有标准 dissoc 的情况下如何做到这一点,那么您可以使用:

      (reduce (fn [m k] (remove-key k m)) {:foo 1 :bar 2 :baz 3} [:foo :bar])
      

      显然,如果您将参数恢复为 remove-key,则可以更简单地编写:

      (reduce remove-key {:foo 1 :bar 2 :baz 3} [:foo :bar])
      

      【讨论】:

        【解决方案4】:

        我发现这种类型的东西和其他类型的东西在 clojure 中非常烦人,所以为了解决它,我创建了库 instar:https://github.com/boxed/instar

        【讨论】:

          猜你喜欢
          • 2017-12-27
          • 1970-01-01
          • 2014-03-24
          • 1970-01-01
          • 2012-02-18
          • 2022-11-10
          • 2021-12-04
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多