确定map是否包含一个键的值?

确定STL映射是否包含给定键的值的最佳方法是什么?

#include <map>


using namespace std;


struct Bar
{
int i;
};


int main()
{
map<int, Bar> m;
Bar b = {0};
Bar b1 = {1};


m[0] = b;
m[1] = b1;


//Bar b2 = m[2];
map<int, Bar>::iterator iter = m.find(2);
Bar b3 = iter->second;


}

在调试器中检查这个,看起来iter只是垃圾数据。

如果我取消注释这一行:

Bar b2 = m[2]

调试器显示b2{i = 0}。(我猜这意味着使用一个未定义的索引将返回一个结构与所有空/未初始化的值?)

这两种方法都不是很好。我真正想要的是这样一个界面:

bool getValue(int key, Bar& out)
{
if (map contains value for key)
{
out = map[key];
return true;
}
return false;
}

是否存在类似的情况?

507120 次浏览

根据end检查find的返回值。

map<int, Bar>::iterator it = m.find('2');
if ( m.end() != it ) {
// contains
...
}

amap.find在没有找到你要找的东西时返回amap::end——你应该检查它。

是否存在类似的情况?

不。对于stl map类,使用::find()搜索映射,并将返回的迭代器与std::map::end()进行比较

所以

map<int,Bar>::iterator it = m.find('2');
Bar b3;
if(it != m.end())
{
//element found;
b3 = it->second;
}

显然,如果你愿意,你可以编写自己的getValue()例程(也是在c++中,没有理由使用out),但我怀疑,一旦你掌握了使用std::map::find()的窍门,你就不会想浪费时间了。

你的代码也有点错误:

m.find('2');将在映射中搜索'2'的键值。IIRC, c++编译器将隐式地将'2'转换为int型,这将导致'2'的ASCII代码的数值不是你想要的。

因为你在这个例子中的键类型是int,你想这样搜索:m.find(2);

它已经在find only中存在,但语法不完全相同。

if (m.find(2) == m.end() )
{
// key 2 doesn't exist
}

如果你想在值存在的情况下访问它,你可以这样做:

map<int, Bar>::iterator iter = m.find(2);
if (iter != m.end() )
{
// key 2 exists, do something with iter->second (the value)
}

使用c++ 0x和auto,语法更简单:

auto iter = m.find(2);
if (iter != m.end() )
{
// key 2 exists, do something with iter->second (the value)
}

我建议你习惯它,而不是试图想出一个新的机制来简化它。您可能能够减少一些代码,但要考虑这样做的成本。现在您已经引入了一个熟悉c++的人无法识别的新函数。

如果不管这些警告,你还是想实现这个,那么:

template <class Key, class Value, class Comparator, class Alloc>
bool getValue(const std::map<Key, Value, Comparator, Alloc>& my_map, int key, Value& out)
{
typename std::map<Key, Value, Comparator, Alloc>::const_iterator it = my_map.find(key);
if (it != my_map.end() )
{
out = it->second;
return true;
}
return false;
}

你可以用下面的代码创建getValue函数:

bool getValue(const std::map<int, Bar>& input, int key, Bar& out)
{
std::map<int, Bar>::iterator foundIter = input.find(key);
if (foundIter != input.end())
{
out = foundIter->second;
return true;
}
return false;
}

只要映射不是multimap,最优雅的方法之一就是使用count方法

if (m.count(key))
// key exists

如果元素确实存在于映射中,则计数为1。

如果你想确定map中是否有一个键,你可以使用map的find()或count()成员函数。 本例中使用的find函数返回element或map::end的迭代器。 在count的情况下,如果找到count则返回1,否则返回0(或其他)
if(phone.count(key))
{ //key found
}
else
{//key not found
}


for(int i=0;i<v.size();i++){
phoneMap::iterator itr=phone.find(v[i]);//I have used a vector in this example to check through map you cal receive a value using at() e.g: map.at(key);
if(itr!=phone.end())
cout<<v[i]<<"="<<itr->second<<endl;
else
cout<<"Not found"<<endl;
}

Boost多索引可用于适当的解决方案。 下面的解决方案不是一个很好的选择,但可能在少数情况下有用,用户在初始化时分配默认值,如0或NULL,并希望检查值是否已修改

Ex.
< int , string >
< string , int >
< string , string >


consider < string , string >
mymap["1st"]="first";
mymap["second"]="";
for (std::map<string,string>::iterator it=mymap.begin(); it!=mymap.end(); ++it)
{
if ( it->second =="" )
continue;
}

我只是注意到C + + 20,我们将有

bool std::map::contains( const Key& key ) const;

如果map包含键为key的元素,则返回true。

简单总结一下其他的一些答案:

如果你还没有使用c++ 20,你可以编写自己的mapContainsKey函数:

bool mapContainsKey(std::map<int, int>& map, int key)
{
if (map.find(key) == map.end()) return false;
return true;
}

如果你想避免mapunordered_map以及不同键和值类型的多次重载,你可以将其创建为template函数。

如果你正在使用C++ 20或更高版本,将会有一个内置的contains函数:

std::map<int, int> myMap;


// do stuff with myMap here


int key = 123;


if (myMap.contains(key))
{
// stuff here
}

Map提供了2个成员函数来检查Map中给定的键是否存在不同的返回值。

  1. std::map::find(返回迭代器)

  2. std::map::count(返回计数)

  • 使用std::map::count检查map是否包含键

它发现&返回map中键为k的元素个数的计数,因为map只包含键为唯一的元素。因此,如果key存在,它将返回1,否则为0。

  • 使用std::map::find检查map是否包含键
它检查map中是否存在键值为' k '的元素,如果存在,则返回其迭代器else 它返回map的结束

更多细节和例子参考下面的链接(容易理解的解释)。

信贷:https://thispointer.com/how-check-if-a-given-key-exists-in-a-map-c/