Multiple index maps

F

fgh.vbn.rty

I am frequently using maps like the following:
map<string, map<int, vector< pair<int, int> > > > m1;
map<int, map<string, map<int, int> > > m2;

This can be a little difficult to maintain if another coder doesn't
really know the what the indexes stand for, the ordering of the
indexes, etc.,

Is there a better way to define multiple index maps? Of course, I can
typedef the inner maps into something more readable but is that always
good?

Sometimes the index ordering matters and sometimes it doesn't. Does
that make a difference?
 
R

rep_movsd

Can you explain what the maps represent?

That would allow us to make sensible suggestions...

Vivek
 
T

tharinda_g

I am frequently using maps like the following:
map<string, map<int, vector< pair<int, int> > > > m1;
map<int, map<string, map<int, int> > > m2;

This can be a little difficult to maintain if another coder doesn't
really know the what the indexes stand for, the ordering of the
indexes, etc.,

Is there a better way to define multiple index maps? Of course, I can
typedef the inner maps into something more readable but is that always
good?

Sometimes the index ordering matters and sometimes it doesn't. Does
that make a difference?

why can't you use a struct to contain the multiple keys and use a
compare functor to compare the compound key.
 
F

fgh.vbn.rty

Can you explain what the maps represent?

That would allow us to make sensible suggestions...

Vivek

Well, each index/key represents some property. For instance,
map<int, map<string, vector<int> > > m1;

The first int key can be something like an enum of a color type (dark,
light, etc.,) and the second string key may be the color name. So if I
wanted "dark green integers" I would need m1[DARK]["green"].

In general the indexes are independent of each other.
 
F

fgh.vbn.rty

why can't you use a struct to contain the multiple keys and use a
compare functor to compare the compound key.

Can you show me an example on how to construct the struct and the
compound key? Thanks.
 
K

Kai-Uwe Bux

Can you explain what the maps represent?

That would allow us to make sensible suggestions...

Vivek

Well, each index/key represents some property. For instance,
map<int, map<string, vector<int> > > m1;

The first int key can be something like an enum of a color type (dark,
light, etc.,) and the second string key may be the color name. So if I
wanted "dark green integers" I would need m1[DARK]["green"].

In general the indexes are independent of each other.

Magic typing is about just as bad as using magic numbers. You might want to
consider using typedefs:

typedef int color_shade;
typedef string color_name;
...

and then

map< color_shade, map< color_name, ... > >


Best

Kai-Uwe Bux
 
T

tharinda_g

Can you show me an example on how to construct the struct and the
compound key? Thanks.

#include <map>
#include <string>
#include <iostream>

typedef int color_shade;
typedef std::string color_name;

enum COLOR_SHADES
{
CS_DARK,
CS_LIGHT
};

class CompoundKey
{
public:
struct Compare //This is what I called a functor
{
bool operator()(CompoundKey Left, CompoundKey Right)
{
int iDiff = Left.cs_Shade - Right.cs_Shade;

if(iDiff != 0)
{
return iDiff < 0; //to sort ascending, > 0 to sort descending
}

return strcmp(Left.cn_Name.c_str(), Right.cn_Name.c_str()) < 0;
}
};

CompoundKey(int iKey1, const char* zKey2)
: cs_Shade(iKey1), cn_Name(zKey2)
{
}

CompoundKey(const CompoundKey& rKey)
:cs_Shade(rKey.cs_Shade), cn_Name(rKey.cn_Name) //Copy constructor
to make sure things are copied correctly
{
}

CompoundKey& operator=(CompoundKey& rKey) //Overload the assignment
so the things are copied correctly
{
cs_Shade = rKey.cs_Shade;
cn_Name = rKey.cn_Name;

return *this;
}

~CompoundKey()
{
}

color_shade cs_Shade;
color_name cn_Name;
};

typedef std::map<CompoundKey, int, CompoundKey::Compare> COLOR_MAP;

int main(int argc, char* argv[])
{
COLOR_MAP mapTest;

mapTest[CompoundKey(CS_DARK, "Blue")] = 0xFF0000;
mapTest[CompoundKey(CS_LIGHT, "Red")] = 0xFF;

COLOR_MAP::iterator ite = mapTest.begin();

for (; ite != mapTest.end() ; ++ite)
{
std::cout << "Shade :" << ite->first.cs_Shade
<< ", Name : " << ite->first.cn_Name
<< ", Value : " << ite->second << std::endl;
}

return 0;
}

This is just an example for what I said. But this will be more useful
if you replace the compound key with some class with a color shade,
name and also the value. Also there is an an alternative for the
functor in this instance. Just overload the operator< of the compound
key with the same implementation inside.
 
M

Michael DOUBEZ

(e-mail address removed) a écrit :
why can't you use a struct to contain the multiple keys and use a
compare functor to compare the compound key.

Or, if there are only two index, simply using std::pair<>
typedef pair<string, int> key_color;
map< key_color , vector< pair<int, int> > > m1;
map< key_color , map<int, int> > m2;

And then

m1[key_color("foo",42)];
 
J

Joe Gottman

I am frequently using maps like the following:
map<string, map<int, vector< pair<int, int> > > > m1;
map<int, map<string, map<int, int> > > m2;

This can be a little difficult to maintain if another coder doesn't
really know the what the indexes stand for, the ordering of the
indexes, etc.,

Is there a better way to define multiple index maps? Of course, I can
typedef the inner maps into something more readable but is that always
good?

Sometimes the index ordering matters and sometimes it doesn't. Does
that make a difference?

You might want to try the boost's multi-index container library:

http://www.boost.org/doc/libs/1_35_0/libs/multi_index/doc/index.html

Joe Gottman
 
G

gpderetta

I am frequently using maps like the following:
map<string, map<int, vector< pair<int, int> > > > m1;
map<int, map<string, map<int, int> > > m2;

This can be a little difficult to maintain if another coder doesn't
really know the what the indexes stand for, the ordering of the
indexes, etc.,

Boost.MultiIndex containers do exactly that.

HTH,
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top