C++ 检查 unordered_maps 的 unordered_map 是否包含键的最简单方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34512437/
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
Simplest method to check whether unordered_map of unordered_maps contains key
提问by user997112
I am using an unordered_map of unordered_maps, such that I can reference an element using the "multi key" syntax:
我正在使用 unordered_maps 的 unordered_map,这样我就可以使用“多键”语法引用一个元素:
my_map[k1][k2]
.
my_map[k1][k2]
.
Is there a convenient way to use the same "multi-key" syntax to check whether an element exists before trying to access it? If not, what is the simplest way?
在尝试访问元素之前,是否有一种方便的方法可以使用相同的“多键”语法来检查元素是否存在?如果没有,最简单的方法是什么?
回答by Cory Kramer
If your intention is to test for the existence of the key, I would not use
如果您的目的是测试密钥是否存在,我不会使用
my_map[k1][k2]
because operator[]
will default construct a new value for that key if it does not already exist.
因为operator[]
如果该键不存在,它将默认为该键构造一个新值。
Rather I would prefer to use std::unordered_map::find
. So if you are certain the first key exists, but not the second you could do
相反,我更愿意使用std::unordered_map::find
. 因此,如果您确定第一个键存在,但第二个键不存在,您可以这样做
if (my_map[k1].find(k2) != my_map[k1].end())
{
// k2 exists in unordered_map for key k1
}
If you would like to make a function that checks for the existence of bothkeys, then you could write something like
如果您想创建一个检查两个键是否存在的函数,那么您可以编写类似
//------------------------------------------------------------------------------
/// \brief Determines a nested map contains two keys (the outer containing the inner)
/// \param[in] data Outer-most map
/// \param[in] a Key used to find the inner map
/// \param[in] b Key used to find the value within the inner map
/// \return True if both keys exist, false otherwise
//------------------------------------------------------------------------------
template <class key_t, class value_t>
bool nested_key_exists(std::unordered_map<key_t, std::unordered_map<key_t, value_t>> const& data, key_t const a, key_t const b)
{
auto itInner = data.find(a);
if (itInner != data.end())
{
return itInner->second.find(b) != itInner->second.end();
}
return false;
}
回答by Yakk - Adam Nevraumont
template<class M>
bool contains(M const&){return true;}
template<class M, class K, class...Ks>
bool contains(M const&m, K const&k, Ks const&...ks){
auto it=m.find(k);
if (it==m.end()) return false;
return contains(it->second, ks...);
}
will work for every single-valued associative container.
将适用于每个单值关联容器。
contains(my_map, k1, k2)
is true if there is an element k1
which contains k2
.
contains(my_map, k1, k2)
如果存在k1
包含的元素,则为真k2
。
回答by Richard Hodges
Something like this? (for the mutable case)
像这样的东西?(对于可变情况)
using inner_map = std::map<key_type, value_type>;
using outer_map = std::map<key_type, inner_map>
boost::optional<value_type&>
element_for_keys(outer_map& map, const key_type& k1, const key_type& k2)
{
auto it_outer = map.find(k1);
if (it_outer = map.end())
return {};
auto &map2 = it_outer->second;
auto it_inner = map2.find(k2);
if (it_inner == map2.end())
return {};
return { it_inner->second };
}
called like so:
像这样调用:
auto op_value = element_for_keys(my_map, kv1, kv2);
if (op_value) {
// use op_value.value()
}
else {
// handle case where it does not exist
}
... or there's the more python-like way...
......或者有更像蟒蛇的方式......
try {
auto& v = my_map.at(k1).at(k2);
// use v
}
catch(const std::out_of_range & e) {
// didn't find it
}
回答by Hui Liu
You might also use count (http://www.cplusplus.com/reference/unordered_map/unordered_map/count/)
您也可以使用计数(http://www.cplusplus.com/reference/unordered_map/unordered_map/count/)
which will return 0 if key not exist
如果键不存在,它将返回 0
回答by pooya13
In C++20, you can use the contains
method (added to all associative containers if I am not mistaken):
在 C++20 中,您可以使用该contains
方法(如果我没记错的话,添加到所有关联容器中):
if (my_map.contains(k1) && my_map[k1].contains(k2))
{
// do something with my_map[k1][k2]
}