2011-09-05 13 views
6

Wciąż pracujemy nad Programowaniem Zbiorowej Inteligencji i użyciem Clojure do napisania kodu. Mam to działa, ale niektóre części są naprawdę brzydkie, więc pomyślałem, że poproszę niektórych ekspertów tutaj, aby pomogli to posprzątać.Usuwanie elementów z mapy na podstawie zawartości innej mapy

Załóżmy Mam mapę, która wygląda następująco (związany z "REC«):

{"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} 

i chcę usunąć te elementy z kluczy, które są również w mapie (związany z» mymovies „):

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

tak że dostanę mapę:

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

kod, który udało mi się zrobić to wygląda:

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

To wydaje się dość brzydki do mnie. Wygląda na to, że nie powinno być konieczne tworzenie mapy z wartości, którą otrzymuję z "usunięcia". Czy istnieje lepszy sposób na zrobienie tego?

AKTUALIZACJA: Odpowiedź Joosta poniżej wywołała inny pomysł. Jeśli zwracam klucze dwóch map w zestawy można używać select-klucze tak:

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

Joost, dzięki za mnie nakręca do select-kluczy. Nie wiedziałem o tej funkcji wcześniej. Teraz można przepisać kilka innych sekcji za pomocą tej nowej znalezionej wiedzy!

Odpowiedz

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

Nice! Nie wiem, jak tęskniłem za tą funkcją. Tyle funkcji do zapamiętania i zapamiętania ... –

+0

Co Dave powiedział :) –

2

Poniżej przedstawiono pierwsze klucze, które należy zachować, a następnie wyodrębnia się "submap" dla tych kluczy z recs za pomocą klawiszy wyboru. Wykorzystuje również fakt, że zestawy są predykatami.

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

myślę odpowiedź ponzao jest najlepszy w tym przypadku, ale nie pomyślał, aby zastosować dissoc. Oto dwa rozwiązania, które mogłem wymyślić: mam nadzieję, że ich przeglądnie pomoże w podobnych przyszłych problemach.

Należy zauważyć, że drugie rozwiązanie zakończy się niepowodzeniem, jeśli Twoja mapa mymovies zawiera wartości zerowe lub fałszywe.

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

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