简体   繁体   中英

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

So I have a list like the following:

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

My goal is to search the list of map items and find duplicates keys, if there are duplicates then increment the quantity. So in the list I have two tuna mapped elements that show up. I want to remove one and just increment the quantity of the other. So the result should be:

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

With :quantity of tuna incremented to 2. I have attempted to use recur to do this without success, I'm not sure if recur is a good direction to run with. Could someone point me in the right direction?

You can group-by :name your elements and then map through the grouped collection summing the values.

Something like this

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

PS I assume you need to sum quantity of elements, because it's not clear what exactly you need to increment.

This is standard use case for map and 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))))

I am using identity to return the element in case you wish to use other properties in the map to determine uniqueness. If the map only contains two fields, then you could simplify it down to

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

Why not just hold a map from name to quantity . Instead of

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

... we have

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

We are using the map to represent a multiset . Several clojure implementations are available, but I haven't used them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM