473,698 Members | 2,611 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Sort a map using the value, not the key.

Hello,

I was wondering if it was posibble to sort a map using the values and not
the keys. Sorting on the keys (if they were strings, for example) is
currently possible. What about, for example, if I have a map with string
keys and object values, can I have custom sorting of the items in the map
based on member variables of said object?

Any help would be appreciated. Thanks.

Cheers,
Diego
Jul 19 '05 #1
7 17676

"Diego Barros" <drylight_@_yah oo.com> wrote in message
news:bh******** ***@otis.netspa ce.net.au...
Hello,

I was wondering if it was posibble to sort a map using the values and not
the keys. Sorting on the keys (if they were strings, for example) is
currently possible. What about, for example, if I have a map with string
keys and object values, can I have custom sorting of the items in the map
based on member variables of said object?

Any help would be appreciated. Thanks.

Cheers,
Diego


Its the sorting on the keys that makes a map work, so no, you cannot have a
map that is sorted on the values.

Why do you want a map sorted on values? There are probably several things
you could do instead. If you explain what you are trying to achieve someone
will suggest a solution.

john
Jul 19 '05 #2

"Rob Williscroft" <rt*@freenet.RE MOVE.co.uk> wrote in message
news:Xn******** *************** ***********@195 .129.110.200...
Diego Barros wrote in news:bh******** ***@otis.netspa ce.net.au:
Basically there is existing code which has a map of objects. Each
object has an associated name (string) and that is used as the key in
the map. So sorting is done alphabetically on this name.

I now need to sort based on a member variable of the object, in this
case an integer which specifies sort order. So if there are 20 items
in the map they should be sorted by the sort order value of each
object. If there is more than one object with the same sort order
value then I wish to sort on the object's name (string) member
variable (for that sort order value). Do I maybe need to use something
else likea vector and keep it sorted myself?

#include <map>
#include <string>

struct Object { int value; };
typedef std::map< std::string, Object > main_map_t;
typedef std::map< int, main_map_t::ite rator > lookup_map_t

main_map_t main_map;
lookup_map_t lookup_map;

//...

void index()
{
main_map_t::ite rator ptr, term;

ptr = main_map.begin( );
term = main_map.end();

for ( ; ptr != term; ++ptr )
{
lookup_map[ ptr->second.value ] = ptr;
}
}

void lookup( int key )
{
lookup_map_t::i terator ptr = lookup_map.find ( key );
if ( ptr == lookup_map.end( ) ) return; // or throw ...

std::string const &name = ptr->second->first;
Object &object = ptr->second->second;

// do something
}

HTH

Rob.


That doesn't work since the sort order values can be duplicates. I think I'd
prefer something like this

struct Object { int value; };
typedef std::map< std::string, Object > main_map_t;
typedef std::set< main_map_t::ite rator, lookup_cmp > lookup_set_t;

where lookup_cmp is a function which orders two main_map_iterat ors, i.e.

bool lookup_cmp(main _map_t::iterato r lhs, main_map_t::ite rator rhs)
{
if (lhs->second.value < rhs->second.value )
return true;
if (lhs->second.value > rhs->second.value )
return false;
return lhs->first < rhs->first;
}

Untested code.

john

}
Jul 19 '05 #3

"Rob Williscroft" <rt*@freenet.RE MOVE.co.uk> wrote in message
news:Xn******** *************** ***********@195 .129.110.200...
Diego Barros wrote in news:bh******** ***@otis.netspa ce.net.au:
Basically there is existing code which has a map of objects. Each
object has an associated name (string) and that is used as the key in
the map. So sorting is done alphabetically on this name.

I now need to sort based on a member variable of the object, in this
case an integer which specifies sort order. So if there are 20 items
in the map they should be sorted by the sort order value of each
object. If there is more than one object with the same sort order
value then I wish to sort on the object's name (string) member
variable (for that sort order value). Do I maybe need to use something
else likea vector and keep it sorted myself?

#include <map>
#include <string>

struct Object { int value; };
typedef std::map< std::string, Object > main_map_t;
typedef std::map< int, main_map_t::ite rator > lookup_map_t

main_map_t main_map;
lookup_map_t lookup_map;

//...

void index()
{
main_map_t::ite rator ptr, term;

ptr = main_map.begin( );
term = main_map.end();

for ( ; ptr != term; ++ptr )
{
lookup_map[ ptr->second.value ] = ptr;
}
}

void lookup( int key )
{
lookup_map_t::i terator ptr = lookup_map.find ( key );
if ( ptr == lookup_map.end( ) ) return; // or throw ...

std::string const &name = ptr->second->first;
Object &object = ptr->second->second;

// do something
}

HTH

Rob.


That doesn't work since the sort order values can be duplicates. I think I'd
prefer something like this

struct Object { int value; };
typedef std::map< std::string, Object > main_map_t;
typedef std::set< main_map_t::ite rator, lookup_cmp > lookup_set_t;

where lookup_cmp is a function which orders two main_map_iterat ors, i.e.

bool lookup_cmp(main _map_t::iterato r lhs, main_map_t::ite rator rhs)
{
if (lhs->second.value < rhs->second.value )
return true;
if (lhs->second.value > rhs->second.value )
return false;
return lhs->first < rhs->first;
}

Untested code.

john

}
Jul 19 '05 #4
John Harrison wrote in news:bh******** ****@ID-196037.news.uni-berlin.de:
That doesn't work since the sort order values can be duplicates. I
think I'd prefer something like this
Ok, then my version needs std::multimap<> , and your's needs
std::multiset<> .

struct Object { int value; };
typedef std::map< std::string, Object > main_map_t;
typedef std::set< main_map_t::ite rator, lookup_cmp > lookup_set_t;

where lookup_cmp is a function which orders two main_map_iterat ors,
i.e.

bool lookup_cmp(main _map_t::iterato r lhs, main_map_t::ite rator rhs)
{
if (lhs->second.value < rhs->second.value )
return true;
if (lhs->second.value > rhs->second.value )
return false;
return lhs->first < rhs->first;
}

Untested code.


You don't duplicate Object::value which is possibly better than my
version, though the insert{} and find() cost will be higher.

The killer point though is how do you find anything, since a
main_map_t::ite rator is required you need to get this from
main_map before you can search the lookup set.
Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 19 '05 #5

"Rob Williscroft" <rt*@freenet.RE MOVE.co.uk> wrote in message
news:Xn******** *************** ***********@195 .129.110.201...
John Harrison wrote in news:bh******** ****@ID-196037.news.uni-berlin.de:
That doesn't work since the sort order values can be duplicates. I
think I'd prefer something like this
Ok, then my version needs std::multimap<> , and your's needs
std::multiset<> .


Because my type includes the key from the original map, there is no
possiblity of duplicates.

struct Object { int value; };
typedef std::map< std::string, Object > main_map_t;
typedef std::set< main_map_t::ite rator, lookup_cmp > lookup_set_t;

where lookup_cmp is a function which orders two main_map_iterat ors,
i.e.

bool lookup_cmp(main _map_t::iterato r lhs, main_map_t::ite rator rhs)
{
if (lhs->second.value < rhs->second.value )
return true;
if (lhs->second.value > rhs->second.value )
return false;
return lhs->first < rhs->first;
}

Untested code.


You don't duplicate Object::value which is possibly better than my
version, though the insert{} and find() cost will be higher.

The killer point though is how do you find anything, since a
main_map_t::ite rator is required you need to get this from
main_map before you can search the lookup set.


True enough, but maybe the OP just wants to iterate through in a particular
order.

john
Jul 19 '05 #6
Diego Barros <drylight_@_yah oo.com> wrote in message news:<bh******* ****@otis.netsp ace.net.au>...
I now need to sort based on a member variable of the object [...] If
there is more than one object with the same sort order value then I wish
to sort on the object's name (string) member variable (for that sort
order value). Do I maybe need to use something else likea vector and keep
it sorted myself?


You can use a set with a custom sort function. A set keeps its members
sorted, and uses the function you provide to decide the order.

E.g. for normal C strings we'd use:

struct ltstr
{
bool operator() (const char* s1, const char* s2) const
{
return strcmp(s1, s2) < 0;
}
};

std::set<const char*, ltstr> s;
s.insert(s.end( ), "foo");
s.insert(s.end( ), "bar");

std::copy(s.beg in(), s.end(), std::ostream_it erator<const
char*>(std::cou t, "\n"));

This should print:
bar
foo
Jul 19 '05 #7
Kristoffer Vinther wrote in news:bh******** **@news.net.uni-c.dk:

[snip]
#include <map>
#include <string>

struct Object { int value; };
typedef std::map< std::string, Object > main_map_t;
typedef std::map< int, main_map_t::ite rator > lookup_map_t

main_map_t main_map;
lookup_map_t lookup_map;

//...

void index()
{
main_map_t::ite rator ptr, term;

ptr = main_map.begin( );
term = main_map.end();

for ( ; ptr != term; ++ptr )
{
lookup_map[ ptr->second.value ] = ptr;
}
}

void lookup( int key )
{
lookup_map_t::i terator ptr = lookup_map.find ( key );
if ( ptr == lookup_map.end( ) ) return; // or throw ...

std::string const &name = ptr->second->first;
Object &object = ptr->second->second;

// do something
}

HTH

Rob.
Wouldn't you be required to rebuild the index whenever main_map is
changed? I realize that OP asked only for a sorted set, but I suspect
he also wants efficient searches and updates. If not, why not just
std::copy objects to an std::vector and std::sort them (same
complexity as building the index and probably faster)?


If the OP wants, to make (say) the occasional report then your
solution would be ideal. Except, I'm assuming the OP's objects are
bigger/more complex than the example I gave :), I'd make it a
std::vector of iterators, they could be then sorted with
std::sort using the comparitor John wrote in another sub thread:
bool lookup_cmp(main _map_t::iterato r lhs, main_map_t::ite rator rhs)
{
if (lhs->second.value < rhs->second.value )
return true;
if (lhs->second.value > rhs->second.value )
return false;
return lhs->first < rhs->first;
}


But if recuring searches are required then both the main_map
and the lookup_map above should be put in a user defined class
with sutable insert(), find() (2 version's) and erase() members
defined.
The hybrid data structure needed for efficient searches on both key
and value is not easily constructible from STL containers, I suspect.
Am I wrong?
Well Maybe, but what I describe above is a UDT with 2 data members
and 4 member function's, doesn't seem that OTT.
If iterators remained valid after map insertions, a
solution like the one you propose would be feasible, though.


As John has already pointed out they do, Its a major (i.e. useful)
feature of std ::map, multimap, set and mutliset.
Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 19 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
3543
by: Ireneusz SZCZESNIAK | last post by:
I want to sort a vector with the std::sort function. There are two functions: one with two arguments, the other with three arguments. I am using the one with three arguments. I noticed that there is a huge overhead of using this function, which comes from copying the function object, i.e., the object that compares the elements of the vector, which is passed to the function not by reference but by value. Now, at the end of this mail...
6
2162
by: Mark Miller | last post by:
I have a scheduled job that uses different XSL templates to transform XML and save it to disk. I am having problems with the code below. The problem shows up on both my development machine (Windows XP Pro SP 1, .Net Framework 1.1) and on our production server (Windows 2K SP 4, .Net Framework 1.1). I have simplified the code and data to isolate the problem. When I use the xsl:strip-space (Line 12) declaration in conjunction with the xsl:sort...
11
3884
by: James P. | last post by:
Hello, I have a report with the Priority field is used as sort order and grouping. The problem is the data in this Priority field if sorted in ascending order is: High, Low, and Medium. How could I sort it as: Low, Medium, High? Any suggestion is greatly appreciated, James
1
20538
by: gerrod | last post by:
Hi - Does anyone know a way to created a SortedList (in the System.Collections namespace) that will sort on VALUES instead of KEYS... ? The scenario is this - I have a SortedList containing key-value pairs of UserID - DisplayName for a whole bunch of user objects. The UserID is simply a long, the DisplayName is something like, "Jones, Bill". I want the SortedList to sort the names alphabetically, rather than by
48
4469
by: Alex Chudnovsky | last post by:
I have come across with what appears to be a significant performance bug in ..NET 2.0 ArrayList.Sort method when compared with Array.Sort on the same data. Same data on the same CPU gets sorted a lot faster with both methods using .NET 1.1, that's why I am pretty sure its a (rather serious) bug. Below you can find C# test case that should allow you to reproduce this error, to run it you will need to put 2 data files into current directory...
2
2875
by: jobooker | last post by:
I'm having issues sorting. The short description is, how do I set the select attribute of xsl:sort to be the value of an xsl:variable? The longer description follows: What I want to do is to be able to make a data table sortable by different headers. Right now, I've got javascript that lets you click on a column header, and then it changes the DOM of the xsl file (changes the select attribute of the xsl:sort element) and reapplies the...
15
2790
by: bcochofel | last post by:
Hi, I want to use a variable to sort elements. That var his passed with query string (I'm using Perl CGI to generate XML). Here's a sample of my output: --------------------------------------------- <?xml version="1.0" encoding="iso-8859-1"?> <?xml-stylesheet type="text/xml" href="RR.xsl"?> <!-- $Id: template.xml,v 1.5 2006/12/11 11:13:30 bcochofel Exp $ --> <RR xmlns:xsi="http://www.w3.org/2001/XMLSchema"...
0
1480
by: Amar | last post by:
Hi, I have a generic list with a some objects of a particular class in it. I have implemented a IComparer for the the class and pass it to the List. The list.sort method works fine when the value of the field I want to compare is different, but when all the elements are same, the list still gets sorted(meaning the sequence of the elements still change). For eg. Say the list is filled with object of type A, where in A has a property...
3
4141
by: tshad | last post by:
I have dataGrid that I am filling from a List Collection and need to sort it by the various columns. So I need to be able to sort the Collection and found that you have to set up your own sorting functions to make it work. I have build the following 3 sorting functions for the 3 columns and have to call each one specifically. I am trying to find a way to cut simplify the functions and calls to make this a more
0
8683
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8610
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
1
8902
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8873
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7740
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6528
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5862
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4372
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3052
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.