Search code examples
clojure

Clojure highest 3 values of a map


Hi l'm trying to do a function that returns the 3 most commom strings

  (take 3 (sort-by val > (frequencies s))))

(freq ["hi" "hi" "hi" "ola" "hello" "hello" "string" "str" "ola" "hello" "hello" "str"])

l've got this so far but a noticed that if there are more than 1 string with the same frenquency it won't return. Is there a way to filter the values of the frequencies funcition by their highest (eventually the top 3 highest)?

Thanks in advance.


Solution

  • I would propose slightly different solution which involves inverting frequencies map with group-by value (which is the items' count):

    (->> data
         frequencies
         (group-by val))
    
    ;;{3 [["hi" 3]],
    ;; 2 [["ola" 2] ["str" 2]],
    ;; 4 [["hello" 4]],
    ;; 1 [["string" 1]]}
    

    so the only thing you need is to just sort and process it:

    (->> data
         frequencies
         (group-by val)
         (sort-by key >)
         (take 3)
         (mapv (fn [[k vs]] {:count k :items (mapv first vs)})))
    
    ;;[{:count 4, :items ["hello"]}
    ;; {:count 3, :items ["hi"]}
    ;; {:count 2, :items ["ola" "str"]}]