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

发布于 2024-09-07 08:37:10 字数 760 浏览 1 评论 0原文

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

是否存在类似的东西?

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

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

If I uncomment out this line:

Bar b2 = m[2]

The debugger shows that b2 is {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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

鸩远一方 2024-09-14 08:37:10

只要地图不是多重地图,最优雅的方法之一就是使用 count 方法。

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

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

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.

风向决定发型 2024-09-14 08:37:10

是否存在类似的东西?

不。对于 stl 地图类,您可以使用 ::find()< /code>搜索地图,并将返回的迭代器与 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);

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()

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.

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.

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

以往的大感动 2024-09-14 08:37:10

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

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

拥有如果映射包含带有键 key 的元素,则返回 true。

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

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

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

离鸿 2024-09-14 08:37:10

它已经存在于 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;
}

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

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:

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.

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;
}
风轻花落早 2024-09-14 08:37:10

amap.find 没有找到您要查找的内容时,它会返回 amap::end - 您应该检查一下。

amap.find returns amap::end when it does not find what you're looking for -- you're supposed to check for that.

迷荒 2024-09-14 08:37:10

简洁地总结一些其他答案:

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

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

如果您想避免 map 的许多重载code> 与 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
}

To succinctly summarize some of the other answers:

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

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.

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

std::map<int, int> myMap;

// do stuff with myMap here

int key = 123;

if (myMap.contains(key))
{
  // stuff here
}
败给现实 2024-09-14 08:37:10

检查 findend 的返回值。

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

Check the return value of find against end.

map<int, Bar>::iterator it = m.find('2');
if ( m.end() != it ) { 
  // contains
  ...
}
樱花细雨 2024-09-14 08:37:10

Map提供了2个成员函数来检查map中是否存在给定的键,并具有不同的返回值,即

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

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

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

返回映射中具有键 K 的元素数量。因为映射仅包含具有唯一键的元素。因此,如果键存在,它将返回 1,否则返回 0。

  • 使用 std::map::find 检查映射是否包含键

它检查映射中是否存在具有给定键“k”的任何元素,并且如果是,那么它返回它的迭代器 else
它返回地图的末尾。

有关更多详细信息和示例,请参阅下面的链接(易于理解的解释)。

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

Map provides 2 member functions to check if a given key exists in map with different return values i.e.

  1. std::map::find (returns iterator)

  2. std::map::count (returns count)

  • Check if map contains a key using 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. So, it will return 1 if key exists else 0.

  • Check if map contains a key using 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.

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/

从来不烧饼 2024-09-14 08:37:10

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

You can create your getValue function with the following code:

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;
}
甜警司 2024-09-14 08:37:10

如果想判断某个key是否存在于map中,可以使用map的find()或count()成员函数。
示例中使用的 find 函数将迭代器返回到 element 或 map::end 否则。
如果是 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;
}

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

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;
}
烂人 2024-09-14 08:37:10

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

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.

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文