Sorting a map by its value

Feb 22, 2011 at 2:30pm
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 Feb 22, 2011 at 2:42pm
Feb 22, 2011 at 2:42pm
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 Feb 22, 2011 at 2:44pm
Feb 22, 2011 at 2:44pm
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 Feb 22, 2011 at 2:45pm
Feb 22, 2011 at 2:52pm
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 Feb 22, 2011 at 3:01pm
Feb 22, 2011 at 3:22pm
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;
}

Feb 23, 2011 at 3:35am
That will do. Thanks a Lot.
Topic archived. No new replies allowed.