Как удалить несколько ключей с карты? - PullRequest
31 голосов
/ 15 марта 2012

У меня есть функция, которая удаляет ключ из карты:

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

Ответы [ 4 ]

47 голосов
/ 15 марта 2012

Ваша функция remove-key поддерживается стандартной библиотечной функцией dissoc. dissoc удаляет более одного ключа за раз, но он хочет, чтобы ключи давались непосредственно в списке аргументов, а не в списке. Таким образом, вы можете использовать apply, чтобы "сгладить" его.

(apply dissoc {:foo 1, :bar 2, :baz 3} [:foo :bar])
==> {:baz 3}
44 голосов
/ 15 марта 2012

dissoc удаляет один или несколько ключей с карты:

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

или, если у вас есть ключи в коллекции

(apply dissoc {:foo 1 :bar 2 :baz 3} [:foo :bar])
11 голосов
/ 15 марта 2012

Как говорили другие, используйте встроенную функцию вместо написания своей собственной.

Однако, если это был просто пример, и вы хотите получить ответ о том, как это сделать, если не было стандартного, тогда вы можете использовать:

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

Очевидно, что если вы вернете аргументы для удаления ключа, это можно записать гораздо проще:

(reduce remove-key {:foo 1 :bar 2 :baz 3} [:foo :bar])
1 голос
/ 27 августа 2015

Я обнаружил, что этот тип и другие вещи очень раздражают в clojure, поэтому, чтобы исправить это, я создал библиотечный экземпляр: https://github.com/boxed/instar.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...