【发布时间】:2022-01-10 00:45:55
【问题描述】:
我有一个map<int, map<int,int>> mymap;
对于像这样嵌套的maps,如何使用find()方法?
如果我有map<int,int> mymap, mymap.find(key),它会给出一个结果。但是对于超过 1 个键的嵌套 maps 呢?
【问题讨论】:
标签: c++ data-structures
我有一个map<int, map<int,int>> mymap;
对于像这样嵌套的maps,如何使用find()方法?
如果我有map<int,int> mymap, mymap.find(key),它会给出一个结果。但是对于超过 1 个键的嵌套 maps 呢?
【问题讨论】:
标签: c++ data-structures
还要注意有std::map::at。
如果匹配的键不存在,它会抛出 std::out_of_range,但在您的情况下使用很简单。
auto value = mymap.at(key1).at(key2);
如果您不确定密钥是否存在,您可以捕获此异常或采用Remy's answer 中的方法。
【讨论】:
mymap.find() 将搜索第一个键并将迭代器返回到包含该键关联值的std::pair,即std::map。
然后find() 上的std::map 将搜索第二个键,将迭代器返回到包含其关联值的std::pair,即int。
例如:
map<int, map<int,int>> mymap;
auto it1 = mymap.find(key1);
if (it1 != mymap.end()) {
auto it2 = it1->second.find(key2);
if (it2 != it1->second.end()) {
// use it2->second as needed...
}
}
【讨论】:
之后
auto entry = mymap.find(key);
您发现 entry 是 std::pair 的迭代器,其中包含 (const!) 键和值,在您的情况下后者是另一个映射,所以:
auto subEntry = entry->second.find(subKey)
(当然,提供entry != mymap.end()!)
【讨论】:
提供处理此类情况的工具是一个很好的做法。
所以solution provided by Remy应该采用辅助函数或通用模板的形式:
template<typename T, typename Key>
auto optional_at(T& x, Key&& key)
-> std::optional<typename T::mapped_type>
{
auto it = x.find(std::forward<Key>(key));
if (it == x.end())
return {};
return it->second;
}
template<typename T, typename Key, typename ...Keys>
auto optional_at(T& x, Key&& key, Keys&&...keys)
-> decltype(optional_at(x[key], std::forward<Keys>(keys)...))
{
auto it = x.find(std::forward<Key>(key));
if (it != x.end())
return optional_at(it->second, std::forward<Keys>(keys)...);
return {};
}
//---------------------
int main()
{
std::map<int, std::map<int, std::string>> m{
{1, {{1, "one-one"}}},
{2, {{1, "two-one"}, {2, "two-two"}}}
};
...
print(std::cout, optional_at(m, 1, 2)) << '\n';
print(std::cout, optional_at(m, 2, 1)) << '\n';
print(std::cout, optional_at(m, 2, 2)) << '\n';
...
return 0;
}
那么当使用这个意图时,意图是清晰而简单的。
【讨论】: