2011-09-05 8 views
6

Ancora lavorando attraverso la programmazione di Intelligenza Collettiva e l'utilizzo di Clojure per scrivere il codice. Ho funzionato, ma alcune parti sono davvero brutte, quindi ho pensato di chiedere ad alcuni degli esperti qui intorno di aiutarlo a ripulirlo.Rimozione di elementi da una mappa in base ai contenuti di un'altra mappa

Supponiamo che ho una mappa che assomiglia a questo (legato 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} 

e voglio per rimuovere gli elementi con chiavi che sono anche nella mappa (legato a' MyMovies "):

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

modo che ho la mappa:

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

il codice che sono riuscito ad ottenere per fare questo si presenta come:

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

Questo sembra abbastanza brutto per me. Non sembra che dovrebbe essere necessario creare una mappa dal valore che torno da "rimuovere". C'è un modo più pulito per fare questo?

AGGIORNAMENTO: la risposta di Joost in basso ha suscitato un'altra idea. Se mi rivolgo le chiavi delle due mappe in serie posso usare Select-chiavi come questo:

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

Joost, grazie per avermi accensione per selezionare -chiavi. Prima non sapevo di questa funzione. Ora vai a riscrivere molte altre sezioni con questa nuova conoscenza trovata!

risposta

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

Bello! Non sono sicuro di come ho perso quella funzione. Così tante funzioni da imparare e ricordare ... –

+0

Cosa Dave ha detto :) –

2

Quanto segue prima crea un seq di tasti da conservare, quindi estrae il "submap" per quei tasti da recs utilizzando i tasti di selezione. Sfrutta inoltre il fatto che gli insiemi sono predicati.

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

penso la risposta di ponzao è meglio per questo caso, ma non avrebbe mai pensato di applicare dissoc. Ecco le due soluzioni che avrei potuto trovare: sperare di vederle aiuterà con problemi futuri simili.

Si noti che la seconda soluzione avrà esito negativo se la mappa mymovies contiene valori nulli o falsi.

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

(into {} 
     (remove (comp mymovies key) recs)) 
Problemi correlati