[英]How to sort QMap<QString, myStruct>?
I have a QMap<QString, myStruct>
with 我有一个
QMap<QString, myStruct>
myStruct {
QString firstname;
QString lastname;
QString status;
}
How can I sort this QMap
according to priority order: status
then firstname
then lastname
? 如何根据优先级顺序对此
QMap
进行排序: status
然后是firstname
然后是lastname
?
As far as I understand, you'd like to retrieve the values of the map sorted in the mentioned way, but still have access to the key. 据我所知,你想检索以上述方式排序的地图值,但仍然可以访问密钥。 Right?
对?
Quickly speaking, a map is a collection of <key, value>
pairs automatically sorted by key , then you may try a list of <value, key>
pairs manually sorted by value instead. 快说,地图是一个集
<key, value>
对通过键自动排序,那么你可以尝试的列表<value, key>
对通过价值人工分拣代替。 Something like QList<QPair<myStruct, QString>>
, while overriding the operator<
for myStruct
. 类似于
QList<QPair<myStruct, QString>>
,同时覆盖operator<
for 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;
}
Of course, it is a one-time use structure that doesn't keep updated with your original map, but you mentioned that the map is fixed (constant?) so it may not be a problem then. 当然,它是一次性使用结构,不会与原始地图保持更新,但你提到地图是固定的 (常量?)所以它可能不是问题。
BTW, a QMap
can be used for the inverse look-up but only in the case the values of the myStruct
part are also unique (so they can be used also as a key), otherwise you may overwrite values when constructing the inverse map. 顺便说一下,
QMap
可用于反向查找,但仅在myStruct
部分的值也是唯一的情况下(因此它们也可以用作键),否则您可能在构造逆映射时覆盖值。
Note: The std::tie
is used just to simplify the sorting condition for tuples (so you'd need to include <tuple>
). 注意:
std::tie
仅用于简化元组的排序条件(因此您需要包含<tuple>
)。
UPDATE UPDATE
Answering one of your comments: Yes, you can also specify your own comparison predicate and then avoid overriding the operator<
, but I think it is harder to read and less re-usable: 回答你的一条评论:是的,你也可以指定你自己的比较谓词,然后避免覆盖
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);
});
Of course, you can implement that comparison lambda as you want, I've used the std::tie
again to simplify the logic in the post. 当然,您可以根据需要实现比较lambda,我再次使用
std::tie
来简化帖子中的逻辑。 The downside is that if you need to generate the inverse map in several places you'd have to repeat the lambda expression everywhere (or create a function to create the inverse map of course). 缺点是如果你需要在几个地方生成逆映射,你必须在任何地方重复lambda表达式(或者创建一个函数来创建逆映射)。
As a side note and in case you are curious, lhs
and rhs
refers to left-hand side and right-hand side respectively, in this case they are used as lhs < rhs
by the sorting algorithm for comparing the elements. 作为旁注,如果你好奇,
lhs
和rhs
指左手侧和右手侧 ,在这种情况下,它们被排序算法用作lhs < rhs
用于比较元素。
Finally, if you'd want to avoid the std::tie
you'd have to make the comparisons manually (code below modifies the operator<
of the first version): 最后,如果你想避免使用
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
}
You can't sort a QMap
manually, you'll have to use a QList
(or QVector
) for that and use std::sort
on it. 您无法手动对
QMap
排序,您必须使用QList
(或QVector
)并在其上使用std::sort
。 Use QMap::values()
to extract the values (structs) from the map into a list, then implement a compare function/method and call it with std::sort
. 使用
QMap::values()
将映射中的值(结构)提取到列表中,然后实现比较函数/方法并使用std::sort
调用它。 See cbuchart s answer for some hints how to do this. 有关如何执行此操作的一些提示,请参阅cbuchart的答案。
Keeping map and list in sync when the values change is a different issue, if this is a requirement you should create a separate question, adding a MCVE and more details on what you tried. 在值更改时保持地图和列表同步是一个不同的问题,如果这是一个要求,您应该创建一个单独的问题,添加MCVE以及您尝试的更多详细信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.