Подтвердить что ты не робот

Как удалить несколько ключей с карты?

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

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

Ответ 1

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

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

Ответ 2

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

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

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

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

Ответ 3

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

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

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

Ответ 4

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