如何按照一定的顺序(不是字母顺序)对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应该按照这个顺序排序:

  1. 状态(按照上面的顺序)
  2. 如果状态相同,我们对名字进行排序,这次是按字母顺序排列
  3. 如果名字相同,我们也按字母顺序对姓氏进行排序

所以结果应该是这样的

----------------------------------------------------------
| 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);