从QList中删除重复对象
Remove duplicate object from QList
我有一个QList<MyData>
,其中MyData
有2个成员,int id
(唯一)和QString name
。我想删除所有基于name
的重复条目,并且该条目必须是具有相同name
的其他对象之间最高的id
。有什么建议可以用最快的方式做吗?性能在这里是一个非常重要的因素。
用谷歌搜了一整天后的一些想法:
-
qStableSort()
它基于id(降序),然后循环通过QList
,然后对于每个条目,复制条目到另一个新的QList
,当name
不存在于新的QList
- 使用
QList::toSet
(删除所有重复条目),并提供基于name
的operator==()和qHash()实现,但唯一条目可能没有最高id - 使用
std::list::unique
,但我不确定它是如何工作的。
std::list::unique
可以接受具有以下属性的函数作为参数:
二元谓词,取两个类型相同的值包含在列表中,返回true以删除作为传递的元素容器的第一个参数,否则为false。这应该是一个函数指针或函数对象。
那么在您的情况下,您可以使用以下函数:
bool shouldRemove(MyData first, MyData second)
{
// remove only if they have the same name and the first id
// is smaller than the second one
return ( first.name == second.name &&
first.id <= second.id );
}
简单地调用do,
std::list<MyData> myList = qlist.toStdList();
myList.unique(shouldRemove)
注意,您需要首先对std::list
编辑
似乎你可以使用std::unique
和Qt containers
(如果Qt
是用STL支持构建的)。在这个例子中,你可以这样做:
// lessThan is a function that sorts first by name and then by id
qSort(qList.begin(), qList.end(), lessThan );
QList<MyData>::iterator it = std::unique (qList.begin(), qList.end(), shouldRemove);
qList.erase(it, qList.end());
这个怎么样:
QList<MyData> theList = ...;
QHash<QString, int> nameToIdMap;
for (const MyData& element : theList) {
auto iter = nameToIdMap.find(element.name);
if (iter != nameToIdMap.end() && iter.second > element.id) {
// If item exists in map (name already occured) and the ID is
// bigger than in the current element, just skip the current element.
continue;
}
// Otherwise, insert/overwrite it in the map.
nameToIdMap[element.name] = element.id;
});
// nameToIdMap should now map unique names to highest IDs. If desired,
// you could copy it back into a new list by iterating over the map's entries
// and creating new MyData elements accordingly.
在我看来,这样做的好处是:您不必将列表转换为std
容器,然后再转换回来,如果您找到继续使用QMap
而不是QList
的方法,则只需在初始列表上迭代一次。QHash
会给你平摊O(1)
的查找复杂度。
编辑:改为QHash
.
我通过STL-containers做到了这一点,但我认为将其转换为Qt-containers并不难
<标题>包括#include <list>
#include <set>
#include <iostream>
#include <algorithm>
struct MyData {
int id;
std::string name;
};
struct MyDataSortComparator {
bool operator()( const MyData & left, const MyData & right ) {
if ( left.name < right.name ) {
return true;
}
else if ( left.name > right.name ) {
return false;
}
return left.id > right.id;
}
};
struct MyDataSetComparator {
bool operator()( const MyData & left, const MyData & right ) {
return left.name < right.name;
}
};
int main() {
std::list< MyData > theList = {
{ 1, "Dickson" },
{ 2, "Dickson" },
{ 3, "Dickson" },
{ 2, "borisbn" },
{ 1, "borisbn" }
};
std::set< MyData, MyDataSetComparator > theSet;
theList.sort( MyDataSortComparator() );
std::for_each( theList.begin(), theList.end(), []( const MyData & data ) {
std::cout << data.id << ", " << data.name << std::endl;
} );
std::for_each( theList.begin(), theList.end(), [&theSet]( const MyData & data ) {
theSet.insert( data );
} );
std::cout << "-------------------" << std::endl;
std::for_each( theSet.begin(), theSet.end(), []( const MyData & data ) {
std::cout << data.id << ", " << data.name << std::endl;
} );
}
5美元http://liveworkspace.org/code/wOFnM 标题>
相关文章:
- 线程调用的函数对对象删除是否安全?
- 当我使用dynamic_cast并删除对象删除时,析构函数是如何工作的?
- 使用 com 对象删除计划任务
- C 将对象删除为参考
- C样式对象删除的包装器
- 静态映射中动态分配的对象.删除必要的
- C++指向对象删除的指针数组,"Debug assertion failure!"
- 在其成员函数返回之前,将对象删除是不确定的行为吗?
- Python 对象删除检测
- C++安全对象删除
- Qt:RemoveWidget和对象删除
- Qt对象删除导致崩溃
- 删除由两个shared_pointer实例管理的对象(删除其中一个)
- 顶点缓冲区对象(删除进程)opengl
- 设计 -- 按名称或对象删除
- 提升中的异常:进程间,共享内存对象删除
- 使用std::function和std::bind来存储回调并处理对象删除
- 如何使用智能指针防止双重对象删除
- 指针指向对象删除时自动为空
- 对象层次结构中的对象删除责任