Jump to content
  • Advertisement
Sign in to follow this  
Staffan E

Extracting keys from a std::map

This topic is 3605 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

In our C++ project I find myself in a position where I have a std::map<K,V> of key-value pairs. Now I need to extract a collection of keys in order to know which keys can be used to get values from the map. Is there any built-in functionality for this purpose in the standard library? An alternative approach would be to keep a separate std::vector<K> to track the known keys, but I'd like to avoid it if it's redundant. Thanks for any input.

Share this post


Link to post
Share on other sites
Advertisement
Iterator through the collection and use the first?

for (std::map<Key, Value>::iterator i = collection.begin(); i != collection.end(); ++i)
{
Key key = i->first;
// do something with it here like adding it to a vector
}
(but you can probably use boost to simplify whatever it is you want to do)

Or if you only need to determine the existence of a key, use find().

Share this post


Link to post
Share on other sites
Edit: didn't see that WanMaster already mentioned map.find. This is redundant :).

I'm not sure why you need the list. It sounds the question you have is "Is this key in the map?" If that's the case, the map itself is a good source of key information. Since they are typically implemented as balanced binary trees, this is a fast search.


bool IsKeyInMap(const Key_t& k, const std::map<Key_t,Value_t>& m)
{
std::map<Key_t, Value_t>::const_iterator itFound;
itFound = m.find(k);
return itFound != m.end();
}


Share this post


Link to post
Share on other sites
(Completely Untested)
template <typename TKey, typename TValue>
struct ExtractPairFirst: public std::unary_function< std:pair<TKey, TValue>, const TKey>
{
result_type operator()(const argument_type &arg) const
{
return arg.first;
}
};

typedef ... KeyType;
typedef ... ValueType;

std::map<KeyType, ValueType> WhateverMap;
std::set<KeyType> Keys;
std::transform(WhateverMap.begin(), WhateverMap.end(), inserter(Keys, Keys.end()), ExtractPairFirst<KeyType, ValueType>());

Share this post


Link to post
Share on other sites
Similar to Extrarius, you can get an iterator range that iterates over the keys using a boost::transform_iterator (http://www.boost.org/doc/libs/1_37_0/libs/iterator/doc/transform_iterator.html) and a functor like the one mentioned. (Or, in a year or two, a nice C++ lambda: [](std::map<K,V>::const_reference p) { p.first })

Share this post


Link to post
Share on other sites
Thanks for all your answers. I think I've arrived at a decision. I'll make the simple iteration through the pairs. It'll not be used too often anyway.

Quote:
Original post by Valere
I'm not sure why you need the list. It sounds the question you have is "Is this key in the map?" If that's the case, the map itself is a good source of key information.

I'm working with a "tag" system in our entity manager that allows me to attach any number of string tags to an entity object. This is used in various ways to select subsets of entities and to carry information about them.

The manager class uses a std::map<std::string, std::vector<Entity*>> to emphasis selection of entity groups based on a given string. Also every Entity keeps a std::vector<std::string> to know which tag strings are associated with it. We've found this very convenient to work with.

Now I'm working on a testing functionality in this system. I want to identify which string tags are present in the system as a whole (get my std::vector<std::string>, not to be confused with the ones in Entity) and then use the strings to address the map. Then I'll be able to present information about which entities are associated with every valid tag.

Since this is for testing purposes only I'll go with the easy iteration. Anyway, thanks.

Share this post


Link to post
Share on other sites
Thanks for sharing your design. I'm a big fan of tagging systems to express natural relationships without the big design up front of a hierarchy. Using a map of vectors like this looks to be a good implementation, and I can definitely see the need for the key list.

Cheers!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!