根据另一个地图的内容从地图中删除项目

时间:2011-09-05 19:57:23

标签: clojure

仍然通过编程集体智慧和使用Clojure编写代码。我有它的工作,但有些部分真的很难看,所以我想我会问一些这里的专家帮忙清理它。

假设我有一张看起来像这样的地图(绑定到“ 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}

我想删除那些同样位于地图中的项目(绑定到“ 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

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

Joost,谢谢你转向 select-keys 。我以前不知道那个功能。现在用这个新发现的知识重写其他几个部分!

3 个答案:

答案 0 :(得分:13)

(apply dissoc recs (keys mymovies))

答案 1 :(得分:2)

以下首先构建一系列要保留的密钥,然后提取"子图"使用select-keys从recs中获取这些键。它还利用了集合是谓词的事实。

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

答案 2 :(得分:0)

我认为ponzao的答案最适合这种情况,但我不会想到应用dissoc。以下是我可能提出的两个解决方案:希望查看它们将有助于解决类似的未来问题。

请注意,如果mymovies地图包含nil或false值,则第二个解决方案将失败。

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

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