How to find if a given key exists in a C++ std::map

C++DictionaryStl

C++ Problem Overview


I'm trying to check if a given key is in a map and somewhat can't do it:

typedef map<string,string>::iterator mi;
map<string, string> m;
m.insert(make_pair("f","++--"));
pair<mi,mi> p = m.equal_range("f");//I'm not sure if equal_range does what I want
cout << p.first;//I'm getting error here

so how can I print what is in p?

C++ Solutions


Solution 1 - C++

Use map::find

if ( m.find("f") == m.end() ) {
  // not found
} else {
  // found
}

Solution 2 - C++

To check if a particular key in the map exists, use the count member function in one of the following ways:

m.count(key) > 0
m.count(key) == 1
m.count(key) != 0

The documentation for map::find says: "Another member function, map::count, can be used to just check whether a particular key exists."

The documentation for map::count says: "Because all elements in a map container are unique, the function can only return 1 (if the element is found) or zero (otherwise)."

To retrieve a value from the map via a key that you know to exist, use map::at:

value = m.at(key)

Unlike map::operator[], map::at will not create a new key in the map if the specified key does not exist.

Solution 3 - C++

C++20 gives us std::map::contains to do that.

#include <iostream>
#include <string>
#include <map>
 
int main()
{
    std::map<int, std::string> example = {{1, "One"}, {2, "Two"}, 
                                     {3, "Three"}, {42, "Don\'t Panic!!!"}};
 
    if(example.contains(42)) {
        std::cout << "Found\n";
    } else {
        std::cout << "Not found\n";
    }
}

Solution 4 - C++

You can use .find():

map<string,string>::iterator i = m.find("f");

if (i == m.end()) { /* Not found */ }
else { /* Found, i->first is f, i->second is ++-- */ }

Solution 5 - C++

C++17 simplified this a bit more with an If statement with initializer. This way you can have your cake and eat it too.

if ( auto it{ m.find( "key" ) }; it != std::end( m ) ) 
{
    // Use `structured binding` to get the key
    // and value.
	const auto&[ key, value ] { *it };

	// Grab either the key or value stored in the pair.
	// The key is stored in the 'first' variable and
	// the 'value' is stored in the second.
	const auto& mkey{ it->first };
	const auto& mvalue{ it->second };

	// That or just grab the entire pair pointed
	// to by the iterator.
	const auto& pair{ *it };
} 
else 
{
   // Key was not found..
}

Solution 6 - C++

m.find == m.end() // not found 

If you want to use other API, then find go for m.count(c)>0

 if (m.count("f")>0)
      cout << " is an element of m.\n";
    else 
      cout << " is not an element of m.\n";

Solution 7 - C++

I think you want map::find. If m.find("f") is equal to m.end(), then the key was not found. Otherwise, find returns an iterator pointing at the element found.

The error is because p.first is an iterator, which doesn't work for stream insertion. Change your last line to cout << (p.first)->first;. p is a pair of iterators, p.first is an iterator, p.first->first is the key string.

A map can only ever have one element for a given key, so equal_range isn't very useful. It's defined for map, because it's defined for all associative containers, but it's a lot more interesting for multimap.

Solution 8 - C++

template <typename T, typename Key>
bool key_exists(const T& container, const Key& key)
{
	return (container.find(key) != std::end(container));
}

Of course if you wanted to get fancier you could always template out a function that also took a found function and a not found function, something like this:

template <typename T, typename Key, typename FoundFunction, typename NotFoundFunction>
void find_and_execute(const T& container, const Key& key, FoundFunction found_function, NotFoundFunction not_found_function)
{
	auto& it = container.find(key);
	if (it != std::end(container))
	{
		found_function(key, it->second);
	}
	else
	{
		not_found_function(key);
	}
}

And use it like this:

	std::map<int, int> some_map;
	find_and_execute(some_map, 1,
		[](int key, int value){ std::cout << "key " << key << " found, value: " << value << std::endl; },
		[](int key){ std::cout << "key " << key << " not found" << std::endl; });

The downside to this is coming up with a good name, "find_and_execute" is awkward and I can't come up with anything better off the top of my head...

Solution 9 - C++

map<string, string> m;

check key exist or not, and return number of occurs(0/1 in map):

int num = m.count("f");  
if (num>0) {    
    //found   
} else {  
    // not found  
}

check key exist or not, and return iterator:

map<string,string>::iterator mi = m.find("f");  
if(mi != m.end()) {  
    //found  
    //do something to mi.  
} else {  
    // not found  
}  

in your question, the error caused by bad operator<< overload, because p.first is map<string, string>, you can not print it out. try this:

if(p.first != p.second) {
    cout << p.first->first << " " << p.first->second << endl;
}

Solution 10 - C++

Be careful in comparing the find result with the the end like for map 'm' as all answer have done above map::iterator i = m.find("f");

 if (i == m.end())
 {
 }
 else
 {
 }  

you should not try and perform any operation such as printing the key or value with iterator i if its equal to m.end() else it will lead to segmentation fault.

Solution 11 - C++

Comparing the code of std::map::find and std::map::count, I'd say the first may yield some performance advantage:

const_iterator find(const key_type& _Keyval) const
	{	// find an element in nonmutable sequence that matches _Keyval
	const_iterator _Where = lower_bound(_Keyval); // Here one looks only for lower bound
	return (_Where == end()
		|| _DEBUG_LT_PRED(this->_Getcomp(),
			_Keyval, this->_Key(_Where._Mynode()))
				? end() : _Where);
	}

size_type count(const key_type& _Keyval) const
	{	// count all elements that match _Keyval
	_Paircc _Ans = equal_range(_Keyval); // Here both lower and upper bounds are to be found, which is presumably slower.
	size_type _Num = 0;
	_Distance(_Ans.first, _Ans.second, _Num);
	return (_Num);
	}

Solution 12 - C++

I know this question already has some good answers but I think my solution is worth of sharing.

It works for both std::map and std::vector<std::pair<T, U>> and is available from C++11.

template <typename ForwardIterator, typename Key>
bool contains_key(ForwardIterator first, ForwardIterator last, Key const key) {
    using ValueType = typename std::iterator_traits<ForwardIterator>::value_type;

    auto search_result = std::find_if(
        first, last,
        [&key](ValueType const& item) {
            return item.first == key;
        }
    );

    if (search_result == last) {
        return false;
    } else {
        return true;
    }
}

Solution 13 - C++

map <int , char>::iterator itr;
    for(itr = MyMap.begin() ; itr!= MyMap.end() ; itr++)
    {
        if (itr->second == 'c')
        {
            cout<<itr->first<<endl;
        }
    }

Solution 14 - C++

If you want to compare pair of map you can use this method:

typedef map<double, double> TestMap;
TestMap testMap;
pair<map<double,double>::iterator,bool> controlMapValues;

controlMapValues= testMap.insert(std::pair<double,double>(x,y));
if (controlMapValues.second == false )
{
    TestMap::iterator it;
    it = testMap.find(x);
    
    if (it->second == y)
    {
        cout<<"Given value is already exist in Map"<<endl;
    }
}

This is a useful technique.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionThere is nothing we can doView Question on Stackoverflow
Solution 1 - C++anonView Answer on Stackoverflow
Solution 2 - C++DavidRRView Answer on Stackoverflow
Solution 3 - C++Denis SablukovView Answer on Stackoverflow
Solution 4 - C++Thomas BoniniView Answer on Stackoverflow
Solution 5 - C++WBuckView Answer on Stackoverflow
Solution 6 - C++aJ.View Answer on Stackoverflow
Solution 7 - C++Steve JessopView Answer on Stackoverflow
Solution 8 - C++LambageView Answer on Stackoverflow
Solution 9 - C++hustljianView Answer on Stackoverflow
Solution 10 - C++InvictusView Answer on Stackoverflow
Solution 11 - C++HopeView Answer on Stackoverflow
Solution 12 - C++NutCrackerView Answer on Stackoverflow
Solution 13 - C++Muhammad Ahmad ZafarView Answer on Stackoverflow
Solution 14 - C++EmreSView Answer on Stackoverflow