2012-03-15 17 views

Respuesta

6

clojure.walk es útil en este tipo de situaciones:

(use 'clojure.walk) 
(postwalk #(if (map? %) (dissoc % :foo :bam) %) d) 
+3

El paseo peatonal hace una travesía en profundidad. Supongo que para esta situación una búsqueda transversal de amplitud será mucho mejor en eficiencia porque si se va a eliminar un nodo padre, entonces no necesitaremos atravesar a sus hijos – Ankur

1

Si quisiera aplicar directamente a continuación, me gustaría sugerir algo como esto:

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

Puntos clave a tener en cuenta sobre la implementación:

  • tiene sentido para convertir descendientes en un conjunto: esto permitirá que las pruebas rápidas de miembros si el conjunto de las llaves para retirar es grande
  • hay cierta lógica para asegurar que si un valor no cambia, que Don No es necesario alterar esa parte del mapa. Esta es una ganancia de rendimiento bastante grande si grandes áreas del mapa no se modifican.
Cuestiones relacionadas