Sorting a map by its value

Hi,

I want to sort a <double,double> map by its value. For example if my map contains following entries
1
2
3
4
5
6
7
8
9
10
11
12
13
map<double,double> myMap;
myMap[10.01] = 12.16;
myMap[14.62] = 53.16;
myMap[16.33] = 4.16;
myMap[45.23] = 100.23;
myMap[0.23] = 34.09;

map<double,double>::iterator it;

for(it = myMap.begin(); it != myMap.end() ; it++)
{
cout << (*it)->first << " => " << (*it)->second << endl;
}


This should print


16.33000 => 4.16000
10.01000 => 12.16000
0.23000 => 34.09000
14.62000 => 53.16000
45.23000 => 100.23000



Switching key with value is not helpful because I want to find values from current key.

An example code would be very helpful.

This is my first post. I apologize if I have made any mistakes.
Last edited on
std::map sorts by key and there's no way to change that behaviour
http://www.cplusplus.com/reference/stl/map/ :
Internally, the elements in the map are sorted from lower to higher key value following a specific strict weak ordering criterion set on construction.


You can copy all the contents of the map into a sequence of pair<double,double> and sort it however you want
but it would be quite a time and memory consuming operation
Last edited on
cout << it->first << " => " << it->second << endl;

You were dereferencing the iterator then trying to treat it like a pointer.

Next time, please post the error message.
Last edited on
I'm sorry. I did not compile it. Just want to submit my problem. Thanks for pointing it out. But my problem is not the compilation error.
Last edited on
If you need to sort by both key and value independently, then consider using a boost::multi_index_container instead. This will do exactly what you want.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <iostream>

struct key_tag {};
struct value_tag {};

typedef std::pair< double, double > element_t;

typedef boost::multi_index_container<
    element_t,
    boost::multi_index::indexed_by<
      boost::multi_index::ordered_unique< boost::multi_index::tag< key_tag >,
          boost::multi_index::member< element_t, double, &element_t::first > >,
      boost::multi_index::ordered_unique< boost::multi_index::tag< value_tag >,
          boost::multi_index::member< element_t, double, &element_t::second > >
> >  dataset_t;

typedef dataset_t::index<key_tag>::type  key_index_t;
typedef dataset_t::index<value_tag>::type value_index_t;

int main()
{
    dataset_t data;

    data.insert( element_t( 3.14, 42.0 ) );
    data.insert( element_t( 10.01, 12.16 ) );
    data.insert( element_t( 14.62, 53.16 ) );
    data.insert( element_t( 16.33, 4.16 ) );
    data.insert( element_t( 45.23, 100.23 ) );
    data.insert( element_t( 0.23, 34.09 ) );

     std::cout << "Data sorted by key field:" << std::endl;
     key_index_t& kindex = data.get<key_tag>();
     for( key_index_t::iterator k = kindex.begin(); k != kindex.end(); ++k )
        std::cout << k->first << " ==> " << k->second << std::endl;

     std::cout << "Data sorted by value field:" << std::endl;
     value_index_t& vindex = data.get<value_tag>();
     for( value_index_t::iterator v = vindex.begin(); v != vindex.end(); ++v )
        std::cout << v->first << " ==> " << v->second << std::endl;
}

That will do. Thanks a Lot.
Topic archived. No new replies allowed.