确定 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;
}
这些方面的东西是否存在?
只要地图不是多地图,最优雅的方法之一就是使用 count 方法
if (m.count(key))
// key exists
如果元素确实存在于地图中,则计数将为 1。
这些方面的东西是否存在?
不。使用 stl 地图类,您使用 ::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
比 count
更好地表明意图。此外,count
不返回该项目。如果您阅读 OP 的问题,他想检查是否存在, 并 返回元素。 find
这样做。 count
没有。
我刚刚注意到,使用 C++20,我们将拥有
bool std::map::contains( const Key& key ) const;
如果 map 包含键为 key
的元素,则返回 true。
它已经存在于 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;
}
当 amap.find
找不到您要查找的内容时,它会返回 amap::end
——您应该检查一下。
简明扼要地总结其他一些答案:
如果您还没有使用 C++ 20,您可以编写自己的 mapContainsKey
函数:
bool mapContainsKey(std::map<int, int>& map, int key)
{
if (map.find(key) == map.end()) return false;
return true;
}
如果您想避免 map
与 unordered_map
以及不同的键和值类型的许多重载,您可以将其设为 template
函数。
如果您使用的是 C++ 20
或更高版本,则会有一个内置的 contains
函数:
std::map<int, int> myMap;
// do stuff with myMap here
int key = 123;
if (myMap.contains(key))
{
// stuff here
}
对照 end
检查 find
的返回值。
map<int, Bar>::iterator it = m.find('2');
if ( m.end() != it ) {
// contains
...
}
您可以使用以下代码创建 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;
}
out = foundIter->second
out = foundIter->second
而不是 out = *foundIter
Map 提供了 2 个成员函数来检查给定的键是否存在于具有不同返回值的映射中,即
std::map::find (返回迭代器) std::map::count (返回计数)
使用 std::map::count 检查 map 是否包含键
它使用键 K 查找并返回映射中元素的数量。因为映射仅包含具有唯一键的元素。因此,如果 key 存在则返回 1,否则返回 0。
使用 std::map::find 检查 map 是否包含键
它检查映射中是否存在具有给定键“k”的任何元素,如果存在则返回其迭代器,否则返回映射的结尾。
有关更多详细信息和示例,请参阅以下链接(易于理解的说明)。
学分:https://thispointer.com/how-check-if-a-given-key-exists-in-a-map-c/
如果要判断某个键是否存在于map中,可以使用map的find()或count()成员函数。示例中使用的 find 函数将迭代器返回到 element 或 map::end 否则。在计数的情况下,如果找到计数返回 1,否则返回零(或其他情况)。
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 multiindex可用于适当的解决方案。以下解决方案不是最好的选择,但在用户在初始化时分配默认值(如 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;
}
不定期副业成功案例分享
operator[]
)。find
为您提供 .NET 的TryGetValue
语义,这几乎总是您(尤其是 OP)想要的。