I have a data set that looks like this:
({"1880" 5} {"1951" 6} {"1952" 5} {"1976" 10} {"1902" 7} {"1919" 7} {"1949" 12} {"1814" 4} {"1930" 11})
I am trying to get the key with the highest value. So in the case above I want to get the value "1949"
back. I believe my answer lies with max-key
, however I don't fully understand how max-key
works. For clarity as one answer was about looking at the string value:
I want the string "1949"
as the result because it has the highest number associated with it of 12
Just use max-key
, with a function to grab the val from each map:
(def data
[{"1880" 5} {"1951" 6} {"1952" 5} {"1976" 10} {"1902" 7} {"1919" 7} {"1949" 12} {"1814" 4} {"1930" 11}])
(apply max-key #(val (first %)) data) => {"1949" 12}
You need the first
function to convert each single element map into a MapEntry
. You can then use the val
function to grab value out of the MapEntry:
(first {"1880" 5}) => <#clojure.lang.MapEntry ["1880" 5]>
(val (first {"1880" 5})) => <#java.lang.Long 5>
Be sure to bookmark The Clojure CheatSheet and peruse it often!
first
works for this: Note that you can convert a map into sequence of MapEntry's using either seq
or vec
:
some-map => <#clojure.lang.PersistentArrayMap {:a 1, :b 2}>
(seq some-map) => <#clojure.lang.PersistentArrayMap$Seq ([:a 1] [:b 2])>
(vec some-map) => <#clojure.lang.PersistentVector [[:a 1] [:b 2]]>
You then need the first item from this seq/vector, which is where first
comes in:
(first (vec some-map)) => <#clojure.lang.MapEntry [:a 1]>
Note, however, that first
implicitly calls seq
on whatever you pass to it, so we can skip the conversion and let first
implicitly convert the map into a seq of MapEntry's for us:
(first some-map) => <#clojure.lang.MapEntry [:a 1]>
You can sort your list of maps by the value of each map within it.
(last (sort-by (comp second first) data))
=> {"1949" 12}
But looking at the data, I'm wondering it wouldn't just be a single map rather than a sequence of maps. So I'm going to make the assumption that your data will never have duplicate keys, and then we can work with just a single map structure and it's easier:
(into {} data)
=> {"1919" 7, "1880" 5, "1814" 4, "1902" 7, "1951" 6, "1949" 12, "1976" 10, "1930" 11, "1952" 5}
Then you can get the same answer like this:
(last (sort-by second (into {} data)))
=> ["1949" 12]
You can call first
with these outputs to get just the string "1949"
.
Here's another way to do it, sorting descending with a custom/reversed comparator:
(->> (into {} data)
(sort-by second #(compare %2 %1))
(ffirst))
=> "1949"
Since your keys aren't numbers (they are strings) you can't use max-key
without casting to a number.
You could achieve your desired result with this:
(last (sort (mapcat keys ({"1889" 1} {"1990" 2}))))
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.