如何忽略结构体第二个属性判定相等?Set中Event去重问题
解决方法:修改比较器实现基于
event的去重 C++的std::set判断元素是否重复,靠的是你传入的比较器的严格弱序规则,而不是直接判断相等。简单说:如果比较器判断a < b为假,同时b < a也为假,那么a和b就会被视为等价(重复)元素,第二个元素无法插入set。
你现在的比较器只比较order,所以set只会认为order相同的元素是重复的,这和你的需求不符。要实现“event相同即视为重复”,需要修改比较器的逻辑:
1. 修改EventCompare比较器
让比较器优先以event作为判断依据,只有当event不同时才按event排序;当event相同时,直接返回false,让set判定这两个元素等价。
修改后的代码如下:
#include <set> #include <string> #include <iostream> struct Event { const std::string event; const int order; Event(const std::string& _event, const int& _order):event(_event),order(_order) {} }; struct EventCompare { bool operator()(const Event& lhs, const Event& rhs) { // 优先比较event字段,按字典序排序 if (lhs.event != rhs.event) { return lhs.event < rhs.event; } // 若event相同,返回false,让set认为两者等价(重复) return false; } }; int main() { std::set<Event, EventCompare> events; // 插入第一个login事件 events.insert(Event("login", 1)); // 插入event相同的login事件,会被视为重复,无法插入 auto insertResult = events.insert(Event("login", 2)); if (!insertResult.second) { std::cout << "插入失败:event为login的元素已存在" << std::endl; } // 插入logout事件,正常插入 events.insert(Event("logout", 3)); // 遍历输出,只会看到login(order=1)和logout(order=3) for (const auto& e : events) { std::cout << "event: " << e.event << ", order: " << e.order << std::endl; } return 0; }
2. 额外需求:替换重复event的元素(保留指定order)
如果你希望当event相同时,用新的元素替换旧的(比如保留order更大的),可以先通过find查找是否存在该event的元素,再删除后插入新元素:
// 要插入的新元素 Event newLogin("login", 5); // 查找是否存在event为login的元素(order不影响查找,因为比较器只看event) auto it = events.find(newLogin); if (it != events.end()) { // 删除旧元素 events.erase(it); } // 插入新元素 events.insert(newLogin); // 此时set里的login事件order为5
这样就能完全满足你“忽略order,仅以event判断重复”的需求了。
内容的提问来源于stack exchange,提问作者alekscooper
相关产品推荐
相关产品推荐

