如何按照一定的顺序(不是字母顺序)对QList进行排序?
How to sort QList according to a certain order (not alphabetical)?
我有QList<m_User>
和
m_User {
QString status;
QString firstName;
QString lastName;
QDate joinDate;
QDate leaveDate;
}
status
这里可以是:terminated
, in test
, requested
, activated
.
status
的排序顺序应该是:activated
-> terminated
-> requested
-> in test
这个QList应该按照这个顺序排序:
- 状态(按照上面的顺序)
- 如果状态相同,我们对名字进行排序,这次是按字母顺序排列
- 如果名字相同,我们也按字母顺序对姓氏进行排序
所以结果应该是这样的
----------------------------------------------------------
| firstName | lastName | status | joinDate | leaveDate |
----------------------------------------------------------
| A | C |activated | bla | bla |
| A | D |activated | bla | bla |
| B | E |activated | bla | bla |
| A | F |terminated| bla | bla |
| A | G |terminated| bla | bla |
| B | H |terminated| bla | bla |
| A | I |requested | bla | bla |
| B | I |requested | bla | bla |
| B | K |requested | bla | bla |
| A | L | in test | bla | bla |
| B | L | in test | bla | bla |
| B | M | in test | bla | bla |
您可以将 lessThen 函数添加到 class/struct,然后如果需要,为 qSort 创建转发器。
示例:
class m_User {
public:
bool operator<(const m_User other) const {
return a<other.a;
}
};
template <typename T>
struct ForwardLessThen
{
bool operator()(const T* a, const T* b) const
{
return *a < *b;
}
};
qSort(list.begin(), list.end(), ForwardLessThen<m_User>());
如果你使用 C++11/14,你可以使用 lambdas
QList<const m_User*> l;
qSort(l.begin(), l.end(),
[](const m_User* a, const m_User* b) -> bool { return a->firstName() < b->firstName(); //implement your logic here
});
对于 Qt5,qSort 实际上已被弃用,您应该使用 std::sort 函数。
std::sort(container.begin(), container.end(), qLess<T>());
看看 QtAlgorithms
中基于模板的算法
编辑: 或者,如果您计划使用某种视图模型(如 ListView),您甚至可以实现自己的 QSortFilterProxyModel
bool compareUsers(const m_User &u1, const m_User &u2)
{
if(u1.status != u2.status)
{
//compare all possible combination if statuses of the
//u1 user and u2 user and return which has priority
//example activated has priorty over terminated
if(u1.status == "activated" && u2.status =="terminated")
{
return true;
}
else if(u1.status == "terminated" && u2.status =="activated")
{
return false;
}
...
..
.
}
else if(u1.firstName != u2.firstName)
{
return u1.firstName > u2.firstName;
}
else
{
return u1.lastName > u2.lastName;
}
}
然后在排序函数中调用谓词
QList<m_User> list;
qSort(list.begin(), list.end(), compareUsers);
我有QList<m_User>
和
m_User {
QString status;
QString firstName;
QString lastName;
QDate joinDate;
QDate leaveDate;
}
status
这里可以是:terminated
, in test
, requested
, activated
.
status
的排序顺序应该是:activated
-> terminated
-> requested
-> in test
这个QList应该按照这个顺序排序:
- 状态(按照上面的顺序)
- 如果状态相同,我们对名字进行排序,这次是按字母顺序排列
- 如果名字相同,我们也按字母顺序对姓氏进行排序
所以结果应该是这样的
----------------------------------------------------------
| firstName | lastName | status | joinDate | leaveDate |
----------------------------------------------------------
| A | C |activated | bla | bla |
| A | D |activated | bla | bla |
| B | E |activated | bla | bla |
| A | F |terminated| bla | bla |
| A | G |terminated| bla | bla |
| B | H |terminated| bla | bla |
| A | I |requested | bla | bla |
| B | I |requested | bla | bla |
| B | K |requested | bla | bla |
| A | L | in test | bla | bla |
| B | L | in test | bla | bla |
| B | M | in test | bla | bla |
您可以将 lessThen 函数添加到 class/struct,然后如果需要,为 qSort 创建转发器。 示例:
class m_User {
public:
bool operator<(const m_User other) const {
return a<other.a;
}
};
template <typename T>
struct ForwardLessThen
{
bool operator()(const T* a, const T* b) const
{
return *a < *b;
}
};
qSort(list.begin(), list.end(), ForwardLessThen<m_User>());
如果你使用 C++11/14,你可以使用 lambdas
QList<const m_User*> l;
qSort(l.begin(), l.end(),
[](const m_User* a, const m_User* b) -> bool { return a->firstName() < b->firstName(); //implement your logic here
});
对于 Qt5,qSort 实际上已被弃用,您应该使用 std::sort 函数。
std::sort(container.begin(), container.end(), qLess<T>());
看看 QtAlgorithms
中基于模板的算法编辑: 或者,如果您计划使用某种视图模型(如 ListView),您甚至可以实现自己的 QSortFilterProxyModel
bool compareUsers(const m_User &u1, const m_User &u2)
{
if(u1.status != u2.status)
{
//compare all possible combination if statuses of the
//u1 user and u2 user and return which has priority
//example activated has priorty over terminated
if(u1.status == "activated" && u2.status =="terminated")
{
return true;
}
else if(u1.status == "terminated" && u2.status =="activated")
{
return false;
}
...
..
.
}
else if(u1.firstName != u2.firstName)
{
return u1.firstName > u2.firstName;
}
else
{
return u1.lastName > u2.lastName;
}
}
然后在排序函数中调用谓词
QList<m_User> list;
qSort(list.begin(), list.end(), compareUsers);