468,247 Members | 1,302 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,247 developers. It's quick & easy.

Multiple index maps

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?

Jul 1 '08 #1
9 6883
Can you explain what the maps represent?

That would allow us to make sensible suggestions...

Vivek
Jul 1 '08 #2
On Jul 1, 12:24*pm, fgh.vbn....@gmail.com wrote:
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.
Jul 1 '08 #3
On Jul 1, 2:36 am, rep_movsd <rep.mo...@gmail.comwrote:
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.
Jul 1 '08 #4
On Jul 1, 2:37 am, tharind...@yahoo.com wrote:
On Jul 1, 12:24 pm, fgh.vbn....@gmail.com wrote:
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.
Can you show me an example on how to construct the struct and the
compound key? Thanks.
Jul 1 '08 #5
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

fg*********@gmail.com wrote:
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?
You might make a new (simple) container class and define for it
operator(), see the following example code. If you want, you can define
an overloaded operator() that swaps the arguments, so you can both call
foo(1, "bar") and foo("bar", 1).

- --------------------------------------------
#include <iostream>
#include <string>

using namespace std;

class Foo
{
public:
void operator()( const int& number, const string& name) const;
};

void Foo::operator()( const int& number, const string& name ) const
{
cout << "I got number " << number;
cout << " and string \"" << name << "\"." << endl;
}

int main()
{
Foo foo;
foo(1, "bar");
foo(0, "baz");

return 0;
}
- ------------------------------------------

You can make the class so the data is actually stored in a map of maps,
or a maps with pairs as keys: in this way you hide the implementation
details from the user, who only sees a friendly operator, and get to use
the STL implementation.
You should also implement operator() (const) so that it returns a
(const) reference to your data, just like std::map::operator[] does.

Cheers,
- -Federico
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (GNU/Linux)
Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org

iD8DBQFIae29BIpu+y7DlLcRAnGlAJ92JF8eJwidKf1hIjyH4I EOw6lqJACdF6Zo
kg2rWRjunj4UgK51HTPVyIk=
=4Mjk
-----END PGP SIGNATURE-----
Jul 1 '08 #6
fg*********@gmail.com wrote:
On Jul 1, 2:36 am, rep_movsd <rep.mo...@gmail.comwrote:
>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

Jul 1 '08 #7
On Jul 1, 1:24*pm, fgh.vbn....@gmail.com wrote:
On Jul 1, 2:37 am, tharind...@yahoo.com wrote:
On Jul 1, 12:24 pm, fgh.vbn....@gmail.com wrote:
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.

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::CompareCOLOR_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.

Jul 1 '08 #8
fg*********@gmail.com wrote:
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...doc/index.html

Joe Gottman


Jul 1 '08 #9
On Jul 1, 9:24*am, fgh.vbn....@gmail.com wrote:
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,

--
gpd
Jul 1 '08 #10

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by forums_mp | last post: by
43 posts views Thread by Steven T. Hatton | last post: by
5 posts views Thread by sgdbprog1 | last post: by
4 posts views Thread by Jay G. Scott | last post: by
9 posts views Thread by William Meyer | last post: by
reply views Thread by NPC403 | last post: by
reply views Thread by kermitthefrogpy | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.