Sort a map in C++ by value not by key: map<char, int>

given:

map<char, int> table;

contains:

A 23
B 2
C 26
D 12


I want to have a function that outputs using cout or any ostream:

C 26
A 23
D 12
B 2



polkadotAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

0xC0DEB07Commented:
Map containers can be sorted by key only
You could use other container (probably vector or linked-list of pairs)

To print a container you could use

std::copy(C.begin(), C.end(),std::ostream_iterator<int>(std::cout,"\n"));
jkrCommented:
Use a temp. mat to achieve that, sorting by value would defeat the purpose of that container, e.g.:

map<int, char> tmp;
map<char, int>::iterator i1 = table.begin();

while (i1 != table.end()) {

  tmp.insert(map<char, int>::value_type(i1->second,i1->first));

  ++i1;
}

map<int, char>::iterator i2 = tmp.begin();

while (i1 != tmp.end()) {

  cout << i2->first << " <-> " i2->second << endl;

  ++i2;
}

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
jkrCommented:
Oops, corection, that should have been

map<int, char>::iterator i2 = tmp.begin();

while (i2 != tmp.end()) {

  cout << i2->first << " <-> " i2->second << endl;

  ++i2;
}
Learn SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

polkadotAuthor Commented:
gives me an incomplete output:

for the map:

a 4
b 2
c 2
d 2
f 4

this code gave me:

2 b
4 a

its replacing the 4 f with teh 4 a ... and the 2 c and 2 d with the 2 b...

jkrCommented:
I hate to say that, but I get

#include <map>
#include <iostream>
using namespace std;

int main () {

map<char, int> table;

table.insert(map<char, int>::value_type('A',23));
table.insert(map<char, int>::value_type('B',2));
table.insert(map<char, int>::value_type('C',26));
table.insert(map<char, int>::value_type('D',12));

map<int, char> tmp;
map<char, int>::iterator i1 = table.begin();

while (i1 != table.end()) {

  tmp.insert(map<char, int>::value_type(i1->second,i1->first));

  ++i1;
}

map<int, char>::iterator i2 = tmp.begin();

while (i2 != tmp.end()) {

  cout << i2->first << " <-> " << i2->second << endl;

  ++i2;
}

return 0;
}

2 <-> B
12 <-> D
23 <-> A
26 <-> C

which to me seems to be what you want.
sushrutCommented:
I did not understand the idea of sorting map by value.

Well.. well. well..
There can be a need where u want it sorted by value. But if thats the case, check if you need a map.

jkr, I am sure your solutions works for given input.
Will it work for following ?
A 23
B 23  //duplicate value.
C 26
D 12

If I really need to take care of duplicates, then I would create a class and overload related operators so that data can be kept in vector or list or something like that.

class name_it_whatever
{
char key;
int value;
//overload operators as required
};

Polkadot,
I cant give you code. If you want to learn, then you try coading it. you will learn the best.
DrAskeCommented:
Hi .. jkr's solution is work fine, but if you are using duplicated values then use *multimap* instead ..

int main () {

map<char, int> table;

table.insert(map<char, int>::value_type('A',4));
table.insert(map<char, int>::value_type('B',2));
table.insert(map<char, int>::value_type('C',2));
table.insert(map<char, int>::value_type('D',2));
table.insert(map<char, int>::value_type('F',4));

multimap<int, char> tmp;
map<char, int>::iterator i1 = table.begin();

while (i1 != table.end()) {

  tmp.insert(multimap<char, int>::value_type(i1->second,i1->first));

  ++i1;
}

multimap<int, char>::iterator i2 = tmp.begin();

while (i2 != tmp.end()) {

  cout << i2->first << " <-> " << i2->second << endl;

  ++i2;
}

return 0;
}

regards,Ahmad;
AxterCommented:
Joaquín M López Muñoz has build a bimap class which does have the ability to retrieve keys by value.
See following link for more information and source code:

http://www.codeproject.com/vcpp/stl/bimap.asp
DrAskeCommented:
jkr and I have answered his question ..

regards,Ahmad;
AxterCommented:
Little late now, but IMHO, the link I provided really answred the question.
It gives the functionallity the questioner was looking for.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.