例如我有struct
struct A {
std::string Id;
std::string Name;
Std::string Year;
};
I defined data type look like
std::map<A, int> MyMap;
我把一些项目放到MyMap上。我想找到一个满足以下
之一的项目- MyMap.find(it1); //that return iter if match Id
- MyMap.find(it2); //that return iter if match both Id and Name
- MyMap.find(it3); //that return iter if match all Id, Name,Year
我知道我必须定义运算符&lt;在结构A中,但如何使用上述3个案例定义该工作。或者在这种情况下,哪种数据类型而不是Map适合。
答案 0 :(得分:4)
std::map
只能有一个谓词用于将键与值相关联。
您可以使用标准算法std::find_if
使用不同的谓词来实现此目的,但它会进行线性搜索,而不是有效的地图查找。
如果需要多个谓词来有效地查找元素,那么您需要一个多索引容器。标准库没有这样的东西,但您可以在内部使用多个映射来实现,或者您可以使用Boost中的通用解决方案。
答案 1 :(得分:0)
如果您的研究仍处于同一顺序,您可能会使用以下内容:
struct A {
std::string Id;
std::string Name;
Std::string Year;
};
bool operator < (const A& lhs, const A& rhs) {
return std::tie(lhs.Id, lhs.Name, lhs.Year) < std::tie(rhs.Id, rhs.Name, rhs.Year);
}
auto findById(const std::map<A, int>&m, const std::string& id)
{
auto it = m.lower_bound(A{id, "", ""});
if (it != m.end() && it->first.Id == id) {
return it;
}
return m.end();
}
auto findByIdName(const std::map<A, int>&m, const std::string& id, const std::string& name)
{
auto it = m.lower_bound(A{id, name, ""});
if (it != m.end() && it->first.Id == id && it->first.Name == name) {
return it;
}
return m.end();
}
auto findByIdNameYear(const std::map<A, int>&m,
const std::string& id,
const std::string& name,
const std::string& year)
{
return m.find(A{id, name, year});
}
如果您更喜欢使用std::vector
,则可以使用std::find_if
:
std::vector<A> as = /*...*/;
auto it = std::find_if(as.begin(), as.end(),
[&](const A& a){ return a.Id = id && a.Name = name;} );
if (it == as.end()) {
// Not found
} else {
// use *it as matching A.
}