I need to sort a std::map
by value, then by key. The map contains data like the following:
1 realistically 8 really 4 reason 3 reasonable 1 reasonably 1 reassemble 1 reassembled 2 recognize 92 record 48 records 7 recs
I need to get the values in order, but the kicker is that the keys need to be in alphabetical order after the values are in order. How can I do this?
The idea is to put all data of HashMap into an ArrayList. Then extract all the keys of HashMap into an ArrayList. Next, sort the extracted keys using the Collections. sort() method, and then for each key extract its value using the get() method.
std::map is a sorted associative container that contains key-value pairs with unique keys. Keys are sorted by using the comparison function Compare .
You cannot sort a map, it's an associative container, not a sequential, and associated containers are sorted by some internal order. If you want to only print the int values, you could put them into a std::vector , sort the vector, and print the values.
std::map
will sort its elements by keys
. It doesn't care about the values
when sorting.
You can use std::vector<std::pair<K,V>>
then sort it using std::sort
followed by std::stable_sort
:
std::vector<std::pair<K,V>> items; //fill items //sort by value using std::sort std::sort(items.begin(), items.end(), value_comparer); //sort by key using std::stable_sort std::stable_sort(items.begin(), items.end(), key_comparer);
The first sort should use std::sort
since it is nlog(n)
, and then use std::stable_sort
which is n(log(n))^2
in the worst case.
Note that while std::sort
is chosen for performance reason, std::stable_sort
is needed for correct ordering, as you want the order-by-value to be preserved.
@gsf noted in the comment, you could use only std::sort
if you choose a comparer which compares values
first, and IF they're equal, sort the keys
.
auto cmp = [](std::pair<K,V> const & a, std::pair<K,V> const & b) { return a.second != b.second? a.second < b.second : a.first < b.first; }; std::sort(items.begin(), items.end(), cmp);
That should be efficient.
But wait, there is a better approach: store std::pair<V,K>
instead of std::pair<K,V>
and then you don't need any comparer at all — the standard comparer for std::pair
would be enough, as it compares first
(which is V
) first then second
which is K
:
std::vector<std::pair<V,K>> items; //... std::sort(items.begin(), items.end());
That should work great.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With