使用disj从Clojure中的集合中删除元素

时间:2016-02-08 15:51:07

标签: clojure set

嗨我在试图从一组中移除一个元素时碰到了一堵砖墙。

我有一张卡片地图。

   (def cards
  {
    :card1 {:name "Wisp"              :type "Monster"     :damage 1 :health 1 :cost 0 :charge "t"}
    :card2 {:name "Spider Tank"       :type "Monster"     :damage 3 :health 4 :cost 3}
    :card3 {:name "Boulder Fist Ogre" :type "Monster"     :damage 6 :health 7 :cost 6}

    }
 )

这些牌的套牌(套)。

(def deck1 (set (map cards '(:card1 :card2 :card3))))

当我使用disj尝试删除其中一张卡时,没有任何反应。

(disj deck1 :card1)

我真的不知道为什么。

4 个答案:

答案 0 :(得分:3)

leetwinski在评论中是正确的。 (disj deck1 (:card1 cards))是正确的。

答案 1 :(得分:1)

首先,这不是典型的clojure成语:

'(:card1 :card2 :card3)

这更简单,更清洁:

[:card1 :card2 :card3]

其次,在我看来,你的收藏品有点复杂化。如其他评论中所述,您不能disj不在那里的密钥;您的map函数返回与键:card1等关联的值,因此尝试取消结果上的键将无效。

现在,如果您希望原始地图中的值可能在该地图中重复,那么将其转换为集合的事实就很重要。是否有可能有多张具有相同伤害的Wisp卡等?如果有可能:例如,card5和:card8可能是相同的值,那么将地图转换为集合将删除这些重复项。如果卡片不可能相同,那么地图已经有了无法复制的唯一键,所以我不确定你通过将它转换成一组来获得什么。

答案 2 :(得分:1)

deck1

#{{:name "Wisp", :type "Monster", :damage 1, :health 1, :cost 0, :charge "t"}
  {:name "Spider Tank", :type "Monster", :damage 3, :health 4, :cost 3}
  {:name "Boulder Fist Ogre", :type "Monster", :damage 6, :health 7, :cost 6}}

此套装不包含 :card1。所以(disj deck1 :card1)没有效果。

你想要像

这样的东西
(apply disj deck1 (filter #(= (:name %) "Wisp") deck1))

...删除:name "Wisp"的所有元素 - 只有一个,给予

#{{:name "Spider Tank", :type "Monster", :damage 3, :health 4, :cost 3}
  {:name "Boulder Fist Ogre", :type "Monster", :damage 6, :health 7, :cost 6}}

答案 3 :(得分:0)

您可以避免将其转换为集合,只需使用dissoc即可。 Dissoc适用于地图而不是集合,因此您可以避免额外的类型转换。

user=> (dissoc cards :card1)
{:card2 {:name "Spider Tank", :type "Monster", :damage 3, :health 4, :cost 3},
 :card3 {:name "Boulder Fist Ogre", :type "Monster", :damage 6, :health 7, :cost 6}}