如何检查 clojure 地图中的重复项?

How do I check for duplicates within a map in clojure?

所以我有如下列表:

({:name "yellowtail", :quantity 2} {:name "tuna", :quantity 1} 
{:name "albacore", :quantity 1} {:quantity 1, :name "tuna"})

我的目标是搜索地图项目列表并找到重复键,如果有重复则增加数量。所以在列表中我有两个显示的金枪鱼映射元素。我想删除一个并增加另一个的数量。所以结果应该是:

({:name "yellowtail", :quantity 2} {:name "tuna", :quantity 2} 
{:name "albacore", :quantity 1} )

随着 :quantity of tuna 递增到 2。我尝试使用 recur 来执行此操作但没有成功,我不确定 recur 是否是 运行 with 的好方向。有人能给我指出正确的方向吗?

这是 map 和 reduce 的标准用例。

(->> data 
     (map (juxt :name :quantity identity)) 
     (reduce (fn [m [key qty _]] 
                (update m key (fnil (partial + qty) 0))) 
             {}) 
     (map #(hash-map :name (key %1) :quantity (val %1))))

我正在使用 identity 到 return 元素,以防您希望使用地图中的其他属性来确定唯一性。如果地图只包含两个字段,那么您可以将其简化为

(->> data 
     (mapcat #(repeat (:quantity %1) (:name %1))) 
     (frequencies) 
     (map #(hash-map :name (key %1) :quantity (val %1))))

您可以 group-by :name 您的元素,然后 map 通过分组集合对值求和。

像这样

(->> your-list 
  (group-by :name) 
  (map (fn [[k v]] 
         {:name k :quantity (apply + (map :quantity v))})))   

P.S。我假设您需要对元素的数量求和,因为不清楚您到底需要增加什么。

为什么不拿着一张从 namequantity 的地图。而不是

({:name "yellowtail", :quantity 2} {:name "tuna", :quantity 1} 
{:name "albacore", :quantity 1} {:quantity 1, :name "tuna"})

...我们有

{"yellowtail" 2, "tuna" 1, "albacore" 1}

我们正在使用地图来表示 multiset。有几种 clojure 实现可用,但我没有使用过它们。