2011-09-05 86 views
6

仍在編程Collective Intelligence並使用Clojure編寫代碼。我已經掌握了它的工作原理,但是有些部分確實很難看,所以我想我會請這裏的一些專家幫助清理它。根據另一張地圖的內容從地圖中刪除項目

讓我們假設我有一個地圖,看起來像這樣(綁定到「區域經濟共同體‘):

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

,我想刪除與該也都在地圖(綁定於鍵’這些項目mymovies「):

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

,使我得到了地圖:

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

,我設法做到這一點的代碼如下所示:

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

這似乎很醜陋給我。似乎沒有必要根據我從「刪除」中獲得的值創建映射。有沒有更乾淨的方法來做到這一點?

更新:Joost的回答下面引發了另一個想法。如果我把兩張地圖的鑰匙進入套我可以使用選擇密鑰這樣的:

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

Joost的,謝謝你開啓我選擇密鑰。我以前不知道那個功能。現在要用這個新發現的知識來重寫其他幾個章節!

回答

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

不錯!不知道我錯過了這個功能。如此多的功能,學習和記憶... –

+0

戴夫說什麼:) –

2

以下內容首先構建要保留的密鑰序列,然後使用選擇密鑰從rec中提取這些密鑰的「子圖」。它也利用了集合是謂詞的事實。

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

我覺得ponzao的回答是最適合這種情況下,但我也不會想到申請dissoc。以下是我可能提出的兩個解決方案:希望查看它們將有助於解決類似的未來問題。

請注意,如果您的mymovies映射包含零值或錯誤值,則第二種解決方案將失敗。

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

(into {} 
     (remove (comp mymovies key) recs)) 
相關問題