Reputation:
I want to know that how can I sort an ordered_map
in C++ on the basis of values. Is there any function to do it?
Upvotes: 2
Views: 2251
Reputation: 85371
A map is an associative container. Unlike sequential containers, where you have control over the location of the element, an associative container itself controls the order of the elements. Once the associative container is created, the ordering cannot be changed.
There is no ordered_map
in standard C++. There is std::map
, which is a tree (and therefore the elements already appear sorted based on the comparator) and std::unordered_map
, which is a hash table (the elements are somewhat ordered based on the hash of the key).
Upvotes: 3
Reputation: 3018
No. A std::map
is designed to store elements formed by a combination of a key value and a mapped value, where the key values are used to sort and identify the elements.
To sort by values, you could simply create an inverted map:
template <typename T1, typename T2>
std::map<T2, T1> invert(const std::map<T1, T2> & m)
{
std::map<T2, T1> ret;
for (const auto& e : m)
ret[e.second] = e.first;
return ret;
}
There are many solutions to this problem, and you might prefer one over the other in function of your needs.
Upvotes: 0
Reputation: 314
You can not really change the elements of a std::map
. However, you can use std::vector
to first copy the elements in the vector and then use std::sort()
.
Sort elements of std::map
.
#include<iostream>
#include <map>
#include <vector>
#include <algorithm>
typedef std::pair<std::string,int> pair;
int main()
{
// input map
std::map<std::string,int> map = {
{"two", 2}, {"one", 1}, {"four", 4}, {"three", 3}
};
// create an empty vector of pairs
std::vector<pair> vec;
// copy key-value pairs from the map to the vector
std::copy(map.begin(),
map.end(),
std::back_inserter<std::vector<pair>>(vec));
// sort the vector by increasing order of its pair's second value
// if second value are equal, order by the pair's first value
std::sort(vec.begin(), vec.end(),
[](const pair& l, const pair& r) {
if (l.second != r.second)
return l.second < r.second;
return l.first < r.first;
});
// print the vector
for (auto const &pair: vec) {
std::cout << '{' << pair.first << "," << pair.second << '}' << '\n';
}
return 0;
}
Upvotes: 1
Reputation: 9835
This answer covers the case that you are referring to values inside the map itself.
First off, the container you want is std::map
. There is no ordered_map
in the standard library, only map
or unordered_map
.
You can supply map
with your own comparer so that it sorts it like you want. For example:
struct MyOrder
{
constexpr bool operator()(MyType a, MyType b) const
{
// return true, so that a < b accodring to your definition
}
};
and use it like
std::map<MyType, MyOrder> myMap;
Upvotes: 1
Reputation: 217398
You cannot rearrange elements of (ordered_
)map
(/set
).
You might copy values (and/or keys) into std::vector
and std::sort
that.
Upvotes: 0