C++ 确定 map 是否包含键的值?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3136520/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 12:09:40  来源:igfitidea点击:

Determine if map contains a value for a key?

c++stlmap

提问by Nick Heiner

What is the best way to determine if a STL map contains a value for a given key?

确定 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;

}

Examining this in a debugger, it looks like iteris just garbage data.

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

If I uncomment out this line:

如果我取消注释这一行:

Bar b2 = m[2]

The debugger shows that b2is {i = 0}. (I'm guessing it means that using an undefined index will return a struct with all empty/uninitialized values?)

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

Neither of these methods is so great. What I'd really like is an interface like this:

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

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

Does something along these lines exist?

是否存在沿着这些路线的东西?

回答by pconnell

As long as the map is not a multimap, one of the most elegant ways would be to use the count method

只要地图不是多地图,最优雅的方法之一就是使用计数方法

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

The count would be 1 if the element is indeed present in the map.

如果元素确实存在于地图中,则计数将为 1。

回答by Alan

Does something along these lines exist?

是否存在沿着这些路线的东西?

No. With the stl map class, you use ::find()to search the map, and compare the returned iterator to std::map::end()

不。使用 stl 地图类,您可以::find()用来搜索地图,并将返回的迭代器与std::map::end()

so

所以

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

Obviously you can write your own getValue()routine if you want (also in C++, there is no reason to use out), but I would suspect that once you get the hang of using std::map::find()you won't want to waste your time.

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

Also your code is slightly wrong:

另外你的代码有点错误:

m.find('2');will search the map for a keyvalue that is '2'. IIRC the C++ compiler will implicitly convert '2' to an int, which results in the numeric value for the ASCII code for '2' which is not what you want.

m.find('2');将在地图中搜索一个键值是'2'。IIRC C++ 编译器会将“2”隐式转换为 int,这会导致“2”的 ASCII 代码的数值不是您想要的。

Since your keytype in this example is intyou want to search like this: m.find(2);

由于您在此示例中的键类型是int您想要这样搜索:m.find(2);

回答by stinky472

It already exists with find only not in that exact syntax.

它已经存在于 find 中,但不是在那个确切的语法中。

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

If you want to access the value if it exists, you can do:

如果要访问该值(如果存在),可以执行以下操作:

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

With C++0x and auto, the syntax is simpler:

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

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

I recommend you get used to it rather than trying to come up with a new mechanism to simplify it. You might be able to cut down a little bit of code, but consider the cost of doing that. Now you've introduced a new function that people familiar with C++ won't be able to recognize.

我建议您习惯它,而不是尝试提出一种新机制来简化它。您可能可以减少一点代码,但请考虑这样做的成本。现在您已经引入了一个熟悉 C++ 的人无法识别的新函数。

If you want to implement this anyway in spite of these warnings, then:

如果您尽管有这些警告,仍然想实现这一点,那么:

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;
}

回答by kebs

I just noticed that with C++20, we will have

我刚刚注意到,使用C++20,我们将有

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

That will return true if map holds an element with key key.

如果 map 包含带有 key 的元素,则返回 true key

回答by Alex Martelli

amap.findreturns amap::endwhen it does not find what you're looking for -- you're supposed to check for that.

amap.findamap::end当它没有找到你要找的东西时返回——你应该检查一下。

回答by JaredPar

Check the return value of findagainst end.

检查findagainst的返回值end

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

回答by Kip Streithorst

You can create your getValue function with the following code:

您可以使用以下代码创建 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;
}

回答by cdahms

To succinctly summarize some of the other answers:

简要总结一些其他答案:

If you're not using C++ 20 yet, you can write your own mapContainsKeyfunction:

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

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

If you'd like to avoid many overloads for mapvs unordered_mapand different key and value types, you can make this a templatefunction.

如果您想避免mapvsunordered_map和不同的键和值类型的许多重载,您可以将其设为template函数。

If you're using C++ 20or later, there will be a built-in containsfunction:

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

std::map<int, int> myMap;

// do stuff with myMap here

int key = 123;

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

回答by Prashant Shubham

If you want to determine whether a key is there in map or not, you can use the find() or count() member function of map. The find function which is used here in example returns the iterator to element or map::end otherwise. In case of count the count returns 1 if found, else it returns zero(or otherwise).

如果你想判断一个键是否存在于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;
}

回答by user2761565

Boost multindex can be used for proper solution. Following solution is not a very best option but might be useful in few cases where user is assigning default value like 0 or NULL at initialization and want to check if value has been modified.

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;
}