a shot of dev knowledge

RELATED TAGS

How to sort a map by value in C++

By default, the std::map container in C++​ sorts its elements by keys, not values. There are several ways to sort it by value, all of which involve the usage of​ other C++ std containers:

svg viewer

Using std::vector

This method entails copying the map into a vector of key-value pairs, ​and sorting the vector according to the increasing order of its pair’s second value:

#include <iostream>
#include <map>
#include <vector>
#include <algorithm> // for sort function

using namespace std;

// utility comparator function to pass to the sort() module
bool sortByVal(const pair<string, int> &a, 
               const pair<string, int> &b) 
{ 
    return (a.second < b.second); 
} 

int main()
{
  // create the map
	map<string, int> mymap = {
		{"coconut", 10}, {"apple", 5}, {"peach", 30}, {"mango", 8}
	};

  cout << "The map, sorted by keys, is: " << endl;
  map<string, int> :: iterator it;
  for (it=mymap.begin(); it!=mymap.end(); it++) 
  { 
    cout << it->first << ": " << it->second << endl;
  }
  cout << endl;
 
	// create a empty vector of pairs
	vector<pair<string, int>> vec;

	// copy key-value pairs from the map to the vector
  map<string, int> :: iterator it2;
  for (it2=mymap.begin(); it2!=mymap.end(); it2++) 
  {
    vec.push_back(make_pair(it2->first, it2->second));
  }

	// // sort the vector by increasing order of its pair's second value
  sort(vec.begin(), vec.end(), sortByVal); 

	// print the vector
	cout << "The map, sorted by value is: " << endl;
	for (int i = 0; i < vec.size(); i++)
	{
		cout << vec[i].first << ": " << vec[i].second << endl;
	}
	return 0;
}

In the example above, instead of using a vector, a set can be used.

Using std::multimap

The idea is to make another map, which uses the original map’s values as its keys and the original map’s keys as its values. A multimap is used, instead of a normal map, to cater to values that are not assigned to distinct keys:

#include <iostream>
#include <map>
#include <set>
#include <algorithm>

using namespace std;

// Function to convert a map<key,value> to a multimap<value,key>
multimap<int, string> invert(map<string, int> & mymap)
{
	multimap<int, string> multiMap;

	map<string, int> :: iterator it;
	for (it=mymap.begin(); it!=mymap.end(); it++) 
	{
		multiMap.insert(make_pair(it->second, it->first));
	}

	return multiMap;
}

int main()
{
	// make the map
	map<string, int> mymap = {
		{"coconut", 10}, {"apple", 5}, {"peach", 30}, {"mango", 8}
	};
	cout << "The map, sorted by keys, is: " << endl;
	map<string, int> :: iterator it;
	for (it=mymap.begin(); it!=mymap.end(); it++) 
	{ 
		cout << it->first << ": " << it->second << endl;
	}
	cout << endl;

	// invert mymap using the invert function created above
	multimap<int, string> newmap = invert(mymap);

	// print the multimap
	cout << "The map, sorted by value is: " << endl;
 	multimap<int, string> :: iterator iter;
	for (iter=newmap.begin(); iter!=newmap.end(); iter++) 
	{
		// printing the second value first because the 
		// order of (key,value) is reversed in the multimap
		cout << iter->second << ": " << iter->first << endl; 
	}

	return 0;
}

RELATED TAGS

RELATED COURSES

C++ Fundamentals for Professionals

Learn C++ from Scratch

C++ Standard Library including C++ 14 & C++ 17

View all Courses