2011-09-05 9 views
6

Aún trabajando a través de la Programación de inteligencia colectiva y usando Clojure para escribir el código. Lo tengo funcionando, pero algunas partes son realmente feas, así que pensé en pedirle a algunos de los expertos de aquí que me ayuden a limpiarlo.Eliminación de elementos de un mapa según el contenido de otro mapa

Supongamos que tengo un mapa que tiene este aspecto (con destino a "Recs '):

{"Superman Returns" 3.902419556891574, "Lady in the Water" 2.8325499182641614, 
"Snakes on a Plane" 3.7059737842895792, "The Night Listener" 3.3477895267131017, 
"You, Me and Dupree" 2.651006036204627, "Just My Luck" 2.5309807037655645} 

y quiero quitar esos elementos con teclas que también están en el mapa (con destino a' MyMovies "):

{"Snakes on a Plane" 4.5, "You, Me and Dupree" 1.0, "Superman Returns" 4.0} 

de modo que consiga el mapa:

{"Lady in the Water" 2.8325499182641614, "The Night Listener" 3.3477895267131017, 
"Just My Luck" 2.5309807037655645} 

el código que he conseguido hacer esto se parece a:

(apply merge (map #(hash-map (first %) (second %)) 
       (remove #(contains? mymovies (first %)) 
         recs))) 

Eso parece bastante feo para mí. No parece que sea necesario crear un mapa a partir del valor que obtengo de "eliminar". ¿Hay una manera más limpia de hacer esto?

ACTUALIZACIÓN: La respuesta de Joost a continuación desató otra idea. Si a su vez las llaves de los dos mapas en conjuntos puedo usar Select-llaves como esto:

(select-keys recs (difference (set (keys recs)) 
           (set (keys mymovies)))) 

Joost, gracias por convertir a mí en seleccionar teclas. No sabía acerca de esa función antes. ¡Ahora para reescribir muchas otras secciones con este nuevo conocimiento encontrado!

Respuesta

13
(apply dissoc recs (keys mymovies)) 
+0

¡Agradable! No estoy seguro de cómo me perdí esa función. Tantas funciones para aprender y recordar ... –

+0

Lo que Dave dijo :) –

2

La siguiente primera compilación de un conjunto de claves para mantener, luego extrae el "submapa" para esas claves de recs usando las teclas de selección. También aprovecha el hecho de que los conjuntos son predicados.

(select-keys recs (remove (apply hash-set (keys mymovies)) (keys recs))) 
0

creo que la respuesta de ponzao es el mejor para este caso, pero no habría pensado aplicar dissoc. Aquí están las dos soluciones que podría haber surgido: con suerte, revisarlas ayudará con problemas similares en el futuro.

Tenga en cuenta que la segunda solución fallará si su mapa mymovies contiene valores nulos o falsos.

(into {} 
     (for [[k v] recs 
      :when (not (contains? mymovies k))] 
     [k v])) 

(into {} 
     (remove (comp mymovies key) recs)) 
Cuestiones relacionadas