C++ 如何对QMap进行排序<;QString,myStruct>;?
我有一个带有C++ 如何对QMap进行排序<;QString,myStruct>;?,c++,qt,sorting,qsort,qmap,C++,Qt,Sorting,Qsort,Qmap,我有一个带有 myStruct { QString firstname; QString lastname; QString status; } 如何根据优先级顺序对该QMap进行排序:status然后firstname然后lastname?据我所知,您希望检索以上述方式排序的映射值,但仍然可以访问该键。对吧? 简而言之,映射是一组自动按键排序的对,然后您可以尝试手动按值排序的对列表。类似于QList,同时覆盖操作符
myStruct {
QString firstname;
QString lastname;
QString status;
}
如何根据优先级顺序对该
QMap
进行排序:status
然后firstname
然后lastname
?据我所知,您希望检索以上述方式排序的映射值,但仍然可以访问该键。对吧?
简而言之,映射是一组自动按键排序的
对,然后您可以尝试手动按值排序的
对列表。类似于QList
,同时覆盖操作符
o.lastname)返回false; 返回false;//值等于 }您不能手动对
进行排序,您必须使用QMap
(或QList
)进行排序,并在其上使用QVector
。使用std::sort
QMap::values()。有关如何执行此操作的提示,请参见cbucharts答案
当值更改是另一个问题时,保持地图和列表同步,如果这是一个要求,您应该创建一个单独的问题,添加一个和更多关于您尝试的内容的详细信息。也许您应该使用另一个容器,因为它总是按键排序!实际上,此QMap已修复,我无法再更改:(.所以我在考虑另一个解决方案:因为我的例子中的键是唯一的,所以我会取出所有值作为,然后对这个QList
进行排序,然后将排序后的列表再次放入QMap中。你如何看待这个解决方案?这不会有帮助。当你重新插入地图时,它将被“重新排序”再次根据键。根据您的用例,您可能需要使用两个容器。首先是按键排序的地图,然后是向量(或类似物)使用映射中的结构的引用包装。你可以按照你想要的方式对向量进行排序。非常感谢@cbuchart。你的解决方案非常出色。但是有一件事我不明白。你覆盖了QList
运算符边界,我们有没有除了
之外的其他算法对元素进行排序,这样我们就不必覆盖什么事?@gnasestd::tie
操作员非常感谢@cbuchart。我通过你的回答了解了更多。我接受了。祝你愉快!
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; }
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); });
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 }