c++ - 如何对 QMap<QString, myStruct> 进行排序?

标签 c++ qt sorting qsort qmap

我有一个 QMap<QString, myStruct>

myStruct {
    QString firstname;
    QString lastname;
    QString status;
}

如何对 QMap 进行排序根据优先顺序:status然后firstname然后lastname

最佳答案

据我了解,您想要检索以上述方式排序的 map 值,但仍可以访问键。对吧?

简而言之, map 是<key, value>的集合。对自动按排序,那么你可以试试<value, key>的列表改为按 手动排序。类似于 QList<QPair<myStruct, QString>> , 同时覆盖 operator<对于 myStruct .

struct myStruct {
    QString firstname;
    QString lastname;
    QString status;

    bool operator<(const myStruct& o) const {
      return std::tie(status, firstname, lastname) <
             std::tie(o.status, o.firstname, o.lastname);
    }
};

QMap<QString, myStatus> map; // your original map
QList<QPair<myStatus, QString>> inv;

// Populate the inverted list
for (auto k : map.keys()) {
  inv.append(QPair<myStatus, QString>(map[k], k));
}

std::sort(std::begin(inv), std::end(inv));

for (auto p : inv) {
  qDebug() << p.first.status << p.first.firstname << p.first.lastname << p.second;
}

当然,它是一次性使用的结构,不会与您的原始 map 保持更新,但您提到 map 是固定的(常量?)所以它可能不是那么问题来了。

顺便说一句,QMap可用于反向查找,但仅适用于 myStruct 的值部分也是唯一的(因此它们也可以用作键),否则您可能会在构造逆映射时覆盖值。

注意: std::tie仅用于简化元组的排序条件(因此您需要包含 <tuple> )。

更新

回答您的评论之一:是的,您还可以指定自己的比较谓词,然后避免覆盖 operator< ,但我认为它更难阅读且不太可重用:

std::sort(std::begin(inv), std::end(inv),
  [](const QPair<myStatus, QString>& lhs, const QPair<myStatus, QString>& rhs) {
    return std::tie(lhs.first.status, lhs.first.firstname, lhs.first.lastname) <
           std::tie(rhs.first.status, rhs.first.firstname, rhs.first.lastname);
});

当然,您可以根据需要实现比较 lambda,我使用了 std::tie再次简化帖子中的逻辑。缺点是,如果您需要在多个地方生成逆映射,则必须在所有地方重复 lambda 表达式(当然也可以创建一个函数来创建逆映射)。

作为旁注,如果您好奇,lhsrhs分别指左手边右手边,在本例中它们用作lhs < rhs通过比较元素的排序算法。

最后,如果您想避免 std::tie你必须手动进行比较(下面的代码修改了第一个版本的 operator<):

bool operator<(const myStruct& o) const {
  if (status < o.status) return true;
  if (status > o.status) return false;
  // status == o.status, move to next attribute

  if (firstname < o.firstname) return true;
  if (firstname > o.firstname) return false;
  // firstname== o.firstname, move to next attribute

  if (lastname < o.lastname) return true;
  if (lastname > o.lastname) return false;

  return false; // are equal
}

关于c++ - 如何对 QMap<QString, myStruct> 进行排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46765436/

相关文章:

c++ - 将参数绑定(bind)到信号/槽

sorting - Redis:将多个 HSET 排序集分组并汇总为一个排序集

r - 计算每个日期的单元格数量

c++ - std::unordered_set insert,获取插入项的位置

C++指针不起作用

c++ - 在 STL 容器上向前迭代然后向后迭代

python - 使用 PySide 将数据库列转换为 Python 列表?

具有常量和变量变化的 C++ 模板

qt - QT Creator中的Signal to Slot,connect()函数在哪里?

java - 如何有效地对一个数组进行排序