如何查找给定键是否存在于 C++ std::map 中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1939953/
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-27 21:39:37  来源:igfitidea点击:

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

c++dictionarystl

提问by There is nothing we can do

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?

那么如何打印 p 中的内容呢?

回答by

Use map::find

map::find

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

回答by DavidRR

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

要检查映射中的特定键是否存在,请通过count以下方式之一使用成员函数:

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

The documentationfor map::findsays: "Another member function, map::count, can be used to just check whether a particular key exists."

文档map::find说:“其他部件的功能,map::count可以用来只检查一个特定的键是否存在。”

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

所述文档map::count表示:“因为在地图容器中的所有元素是唯一的,该函数只能返回1(如果该元件被发现),或零(否则)”。

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

要通过您知道存在的键从地图中检索值,请使用map::at

value = m.at(key)

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

map::operator[] 不同map::at如果指定的键不存在,则不会在映射中创建新键。

回答by Denis Sablukov

C++20gives us std::map::containsto do that.

C++20使我们std::map::contains能够做到这一点。

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

回答by Thomas Bonini

You can use .find():

您可以使用.find()

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

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

回答by aJ.

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

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

如果你想使用其他API,那么找到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";

回答by Steve Jessop

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.

我想你想要map::find。如果m.find("f")等于m.end(),则未找到密钥。否则, find 返回一个指向找到的元素的迭代器。

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

错误是因为p.first是一个迭代器,它不适用于流插入。将最后一行更改为cout << (p.first)->first;. p是一对迭代器,p.first是一个迭代器,p.first->first是关键字符串。

A map can only ever have one element for a given key, so equal_rangeisn'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.

对于给定的键,地图只能有一个元素,因此equal_range不是很有用。它是为 map 定义的,因为它是为所有关联容器定义的,但对于 multimap 更有趣。

回答by WBuck

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

C++17使用If statement with initializer. 这样你就可以吃蛋糕了。

if ( auto it{ m.find( "key" ) }; it != std::end( m ) ) 
{
    // Use `structured binding` to get the key
    // and value.
    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.
    auto mkey{ it->first };
    auto mvalue{ it->second };

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

回答by Lambage

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...

这样做的缺点是想出了一个好名字,“find_and_execute”很尴尬,我想不出更好的主意……

回答by hustljian

map<string, string> m;

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

检查键是否存在,并返回出现次数(地图中的 0/1):

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.firstis map<string, string>, you can not print it out. try this:

在你的问题中,错误operator<<过载导致的错误,因为p.firstmap<string, string>,你不能打印出来。尝试这个:

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

回答by Invictus

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");

将查找结果与像 map 'm' 这样的结尾进行比较时要小心,因为所有答案都已在 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.

如果它等于 m.end() ,则不应尝试执行任何操作,例如使用迭代器 i 打印键或值,否则会导致分段错误。