Разобрать несколько потомков ключей карты? - PullRequest
5 голосов
/ 15 марта 2012

Как я могу найти и распустить несколько потомков ключей.

Пример:

(def d {:foo 123
        :bar {
          :baz 456
          :bam {
            :whiz 789}}})

(dissoc-descendents d [:foo :bam])
;->> {:bar {:baz 456}}

Ответы [ 2 ]

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

clojure.walk полезен в таких ситуациях:

(use 'clojure.walk)
(postwalk #(if (map? %) (dissoc % :foo :bam) %) d)
1 голос
/ 19 марта 2012

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

(defn dissoc-descendents [coll descendents]
  (let [descendents (if (set? descendents) descendents (set descendents))]
    (if (associative? coll)
      (reduce
        (fn [m [k v]] (if (descendents k) 
                        (dissoc m k)
                        (let [new-val (dissoc-descendents v descendents)]
                          (if (identical? new-val v) m (assoc m k new-val)))))
        coll
        coll)
      coll)))

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

  • Имеет смысл преобразоватьпотомки в набор: это позволит проводить быстрые тесты членства, если набор удаляемых ключей большой
  • Существует некоторая логика, гарантирующая, что если значение не изменяется, вам не нужно изменять эту частькарты.Это довольно большой выигрыш в производительности, если большие области карты не изменились.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...