根据值查找map中的元素
Finding an element in map by its value
我正在创建一个HandleManager
,其目的是简单地将Handle
s(这是long long int
的typedef
)映射到string
s。这样做的目的是,使用Handle
的对象也可以通过string
来识别,如果它有助于用户记住对象的话。在这种情况下,在这个地图中:
typedef std::unordered_map<Handle, std::string> HandleMap;
对中的两个类型都是键,因为它们可以用来标识任何东西。到目前为止,除了需要获得Handle
的代码外,所有内容都已编译。这样做的目的是,当用户分配string
时,如下所示:
handle("myHandle");
随机生成一个Handle
,然后传递的string
在前面的映射中与它配对。我现在想要的是能够根据传递的string
获得与string
配对的Handle
:
Handle HandleManager::id(const std::string &name)
{
HandleMap::iterator it = pHandles.find(name);
if (it != pHandles.end())
return it->first;
return -1;
}
但是由于一些奇怪的原因,编译器报错了:
HandleManager.cpp:48:45: error: no matching function for call to ‘std::unordered_map<long long int, std::basic_string<char> >::find(const string&)’
在前面的映射中,string
是值,Handle
是键。那么我如何根据其中包含的值从unordered_map
获得键 ?
std::unordered_map::find
操作的是键,而不是值。您可以使用std::find_if
:
Handle HandleManager::id(const std::string &name)
{
auto it = std::find_if(std::begin(pHandles), std::end(pHandles),
[](auto&& p) { return p->second == name; });
if (it == std::end(pHandles))
return -1;
return it->first
}
请注意auto
, std::begin
, std::end
和lambdas是c++ 11,而泛型lambdas是c++ 14,所以如果你坚持使用旧的编译器,请将它们替换掉。
可以使用成员函数find
只搜索key。要搜索值,可以使用带有lambda函数的std::find_if
(如果使用c++ 11),或者遍历映射(在以前的c++版本中是可以的):
for (HandleMap::const_iterator it = map.begin(); it != map.end(); ++it) {
if (it->second == name) return it->first;
}
// or value not found
另一方面,如果搜索值是一个非常常见的操作,您可能希望有两个映射:std::unordered_map<Handle, std::string>
和std::unordered_map<std::string, Handle>
。在这种情况下,你必须确保在两个映射中执行插入、删除等操作,以保持它们的同步。
但是由于一些奇怪的原因,编译器报错了:
当然可以,find
函数是用于按键查找的,而您没有这样做。
要找到一个值,你需要访问每个元素,直到找到它(或者使用双向映射,将值映射回键,例如Boost.Bimap)。
根据@TartanLlama(*)的回答:
Handle HandleManager::id(const std::string & name) {
auto iter = std::find_if(std::begin(pHandles), std::end(pHandles),
[& name](auto && pair) {
return pair.second == name;
});
if (it == std::end(pHandles)) {
return -1;
}
return it->first;
}
(*):因为似乎不可能在注释中格式化代码。
- 为什么在 std::map 上移动无法将元素从一个映射移动到另一个映射
- 使用 map.end() 访问 map 的最后一个元素
- std::map:当元素不可默认构造时创建/替换元素
- 类中的 C++ 全局映射,不要打印 map 元素
- 使用 at() 访问 std::map 元素是否比运算符 [] 慢?
- 在 std::map 中插入数组元素
- 如果键不存在,使用 [] 运算符访问 STL Map 元素会添加新元素
- 为什么 memcpy() 是一种将元素添加到 'std::map' 的方法?
- 如何仅根据第二个元素对map<int,pair<int,int> >进行排序?
- C++ Map erase(),迭代器打印 erased 元素
- C 中MAP的反向迭代错过了第一个元素
- 从 Map 中获取具有给定值的元素
- STD :: MAP-使用下标操作员与插入方法添加元素
- 如何在map::find()函数中引用类元素?
- 如何在STD :: MAP中找到具有至少一个数据成员等于密钥的结构的元素
- 在 std::map 中插入非默认构造元素
- 使用 stl::map 和 stl::unordered_map 对包含大量重复元素的数组数据进行排序
- 如何在 std::map 中找到指定范围内的元素?
- 访问std::map中元素的最有效方法是什么
- 如何在 std::map 中添加元素自己进行分配