Search code examples
clojureclojurescript

Cleaner Way to Sort and Order a Vector of Maps in Clojure?


I have a vector of maps wherein I need to remove the maps where the value of the name key is a duplicate, keeping the one that has the highest value of age. I have a solution but I don't think it looks clean. Is there a better way to do it without breaking it up into multiple functions?

Here is my data:

(def my-maps
    [{:name "jess", :age 32} 
     {:name "ruxpin", :age 4} 
     {:name "jess", :age 35} 
     {:name "aero", :age 33} 
     {:name "banner", :age 4}])

Here is my solution:

(map first (vals (group-by :name (reverse (sort-by :name my-maps)))))

Result:

({:name "ruxpin", :age 4} {:name "jess", :age 35} {:name "banner", :age 4} {:name "aero", :age 33})

Solution

  • another way is the combination of group-by and max-key. The advantage of this method is that you don't need to sort your collection, and sort in turn has an impact on performance and if it can be avoided it should be.

    (for [[_ vs] (group-by :name my-maps)]
      (apply max-key :age vs))
    
    ;;=> ({:name "jess", :age 35} 
    ;;    {:name "ruxpin", :age 4} 
    ;;    {:name "aero", :age 33} 
    ;;    {:name "banner", :age 4})