简体   繁体   English

确定映射是否包含键的值?

[英]Determine if map contains a value for a key?

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 iter is just garbage data.在调试器中检查这个,看起来iter只是垃圾数据。

If I uncomment out this line:如果我取消注释这一行:

Bar b2 = m[2]

The debugger shows that b2 is {i = 0} .调试器显示b2{i = 0} (I'm guessing it means that using an undefined index will return a struct with all empty/uninitialized values?) (我猜这意味着使用未定义的索引将返回一个包含所有空/未初始化值的结构?)

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?是否存在沿着这些路线的东西?

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。

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' .将在地图中搜索为'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. IIRC C++ 编译器会将“2”隐式转换为 int,这会导致“2”的 ASCII 代码的数值不是您想要的。

Since your keytype in this example is int you want to search like this: m.find(2);由于您在此示例中的键类型是int您想这样搜索: m.find(2);

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 。

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

amap.find回报amap::end时,没有找到您要查找的内容-你应该检查这一点。

Check the return value of find against end .根据end检查find的返回值。

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

To succinctly summarize some of the other answers:简要总结一些其他答案:

If you're not using C++ 20 yet, you can write your own mapContainsKey function:如果您还没有使用 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 map vs unordered_map and different key and value types, you can make this a template function.如果您想避免mapunordered_map以及不同的键和值类型的许多重载,您可以将其设为template函数。

If you're using C++ 20 or later, there will be a built-in contains function:如果您使用的是C++ 20或更高版本,则会有一个内置的contains函数:

std::map<int, int> myMap;

// do stuff with myMap here

int key = 123;

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

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

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.如果你想判断一个键是否存在于map中,你可以使用map的find()或count()成员函数。 The find function which is used here in example returns the iterator to element or map::end otherwise.示例中使用的 find 函数将迭代器返回到 element 或 map::end 否则。 In case of count the count returns 1 if found, else it returns zero(or otherwise).在计数的情况下,如果找到,则计数返回 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 multindex can be used for proper solution. Boost multiindex 可用于适当的解决方案。 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.以下解决方案不是最好的选择,但在用户在初始化时分配默认值(如 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;
}

Map provides 2 member functions to check if a given key exists in map with different return values ie Map 提供了 2 个成员函数来检查 map 中是否存在具有不同返回值的给定键,即

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

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

  • Check if map contains a key using std::map::count使用 std::map::count 检查地图是否包含键

It finds & returns the count of number of elements in map with key K. As map contains elements with unique key only.它查找并返回键为 K 的映射中元素的数量。因为映射仅包含具有唯一键的元素。 So, it will return 1 if key exists else 0.因此,如果键存在,则返回 1,否则返回 0。

  • Check if map contains a key using std::map::find使用 std::map::find 检查地图是否包含键

It checks if any element with given key 'k' exists in the map and if yes then it returns its iterator else it returns the end of map.它检查映射中是否存在具有给定键“k”的任何元素,如果是,则返回其迭代器,否则返回映射的结尾。

For more details and examples refer to below link(easy to understand explanation).有关更多详细信息和示例,请参阅以下链接(易于理解的解释)。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM