我想知道是否有一种有效的方法可以根据对象的成员字段值从容器中删除对象。例如,我可以使用带有字符串列表的stl :: unique执行以下操作:
#include<iostream>
#include<list>
#include<string>
#include<algorithm>
using namespace std;
bool stringCompare(const string & l, const string & r)
{
return (l==r);
}
int main()
{
list<string> myStrings;
myStrings.push_back("1001");
myStrings.push_back("1001");
myStrings.push_back("81");
myStrings.push_back("1001");
myStrings.push_back("81");
myStrings.sort();
myStrings.erase(unique(myStrings.begin(), myStrings.end(), stringCompare), myStrings.end());
list<string>::iterator it;
for(it = myStrings.begin(); it != myStrings.end(); ++it)
{
cout << *it << endl;
}
return 0;
}
打印1001,81 ......
有没有办法可以用以下代码做类似的事情,或者我是否需要使用运算符“手动”执行比较并迭代容器。我想不出一个更优雅的解决方案,并想知道如果没有编写大量代码就可以实现这一点。任何帮助都感激不尽!
class Packet
{
public:
Packet(string fTime, string rID) : filingTime(fTime), recordID(rID)
string getFilingTime() {return filingTime;}
string getRecordId() {return recordID;}
private:
string filingTime;
string recordID;
};
int main()
{
vector<Packet*> pkts;
pkts.push_back(new Packet("10:20", "1004"));
pkts.push_back(new Packet("10:20", "1004")); // not unique (duplicate of the line above)
pkts.push_back(new Packet("10:20", "251"));
pkts.push_back(new Packet("10:20", "1006"));
// remove packet from vector if time and ID are the same
return 0;
}
由于
答案 0 :(得分:7)
可以使用std::unique
的两个选项:
为operator==
定义Packet
方法,并将vector<Packet*>
更改为vector<Packet>
。
bool Packet::operator==(const Packet& rhs) const
{
if (getFilingTime() != rhs.getFilingTime())
return false;
if (getSpid() != rhs.getSpid())
return false;
return true;
}
//etc.
int main()
{
vector<Packet> pkts;
pkts.push_back(Packet("10:20", "1004"));
pkts.push_back(Packet("10:20", "1004")); // not unique (duplicate of the line above)
pkts.push_back(Packet("10:20", "251"));
pkts.push_back(Packet("10:20", "1006"));
// remove packet from vector if time and ID are the same
pkts.erase(unique(pkts.begin(), pkts.end()), pkts.end());
return 0;
}
将矢量保持为vector<Packet*>
并定义比较元素的方法。
bool comparePacketPtrs(Packet* lhs, Packet* rhs)
{
if (lhs->getFilingTime() != rhs->getFilingTime())
return false;
if (lhs->getSpid() != rhs->getSpid())
return false;
return true;
}
//etc.
int main()
{
vector<Packet*> pkts;
pkts.push_back(new Packet("10:20", "1004"));
pkts.push_back(new Packet("10:20", "1004")); // not unique (duplicate of the line above)
pkts.push_back(new Packet("10:20", "251"));
pkts.push_back(new Packet("10:20", "1006"));
// remove packet from vector if time and ID are the same
pkts.erase(unique(pkts.begin(), pkts.end(), comparePacketPtrs), pkts.end());
return 0;
}
答案 1 :(得分:4)
作为unique
的替代方法,您只需将元素插入set
(或C ++ 11中的unordered_set
)。
无论您决定采用哪种方式,都需要为Packet
定义比较运算符。对于unique
,您需要operator==
;对于set
,您需要operator<
。为了完整起见,您应该定义它们和它们的对应物:
class Packet {
…
bool operator==(const Packet& p) const {
return fillingTime == p.fillingTime && recordID == p.recordID;
}
bool operator<(const Packet& p) const {
return fillingTime < p.fillingTime ||
(fillingTime == p.fillingTime && recordID < p.recordID);
}
bool operator!=(const Packet& p) const { return !(*this == p); }
bool operator> (const Packet& p) const { return p < *this; }
bool operator>=(const Packet& p) const { return !(*this < p); }
bool operator<=(const Packet& p) const { return !(p < *this); }
…
};
如果您使用C ++ 11的unordered_set
,则需要更进一步并定义哈希函数。
编辑:我刚刚注意到您存储了指向Packet
的指针。为什么?只需直接存储Packet
。