如何对嵌套地图使用 map::find() 方法?
How to use the map::find() method for a nested map?
我有一个map<int, map<int,int>> mymap;
如何对这样的嵌套 map
使用 find()
方法?
如果我有 map<int,int> mymap, mymap.find(key)
它会给出一个结果。但是超过 1 个键的嵌套 map
s 呢?
mymap.find()
将搜索第一个键和 return 指向包含该键关联值的 std::pair
的迭代器,即 std::map
.
然后 find()
std::map
将搜索第二个键,return 将迭代器指向包含其关联值的 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()
!)
还要注意还有std::map::at
.
如果匹配的键不存在,它会抛出 std::out_of_range
,但您的情况的用法很简单。
auto value = mymap.at(key1).at(key2);
如果您不确定密钥是否存在,您可以捕获此异常或使用 中的方法。
最好提供一种工具来处理此类情况。
所以应该采用辅助函数或通用模板的形式:
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;
}
那么使用这个的时候意图就很简单了。
我有一个map<int, map<int,int>> mymap;
如何对这样的嵌套 map
使用 find()
方法?
如果我有 map<int,int> mymap, mymap.find(key)
它会给出一个结果。但是超过 1 个键的嵌套 map
s 呢?
mymap.find()
将搜索第一个键和 return 指向包含该键关联值的 std::pair
的迭代器,即 std::map
.
然后 find()
std::map
将搜索第二个键,return 将迭代器指向包含其关联值的 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()
!)
还要注意还有std::map::at
.
如果匹配的键不存在,它会抛出 std::out_of_range
,但您的情况的用法很简单。
auto value = mymap.at(key1).at(key2);
如果您不确定密钥是否存在,您可以捕获此异常或使用
最好提供一种工具来处理此类情况。
所以
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;
}
那么使用这个的时候意图就很简单了。