Контейнеры QMap и QSet в Qt представляют собой ассоциативные структуры данных. Они уже отсортированы, но по ключу (QMap) или по значению (QSet) в естественном порядке, определяемом оператором <. Однако на практике часто требуется:
- Отсортировать
QMapпо значению, а не по ключу - Отсортировать
QSetв специфичном порядке (например, по убыванию)
В этой статье мы рассмотрим, как это сделать на практике с использованием std::sort, QVector и лямбда-функций
Сортировка QMap по значениям
Допустим, у нас есть карта QMap<QString, int>, где ключ — это имя, а значение — возраст:
QMap<QString, int> ages = {
{"Alice", 30},
{"Bob", 25},
{"Charlie", 35}
};
Цель: отсортировать по возрасту (значению)
Так как QMap по умолчанию сортируется по ключу, для сортировки по значению нужно:
- Преобразовать данные в
QVector<QPair<QString, int>> - Отсортировать вектор
- Использовать результат по необходимости
QVector<QPair<QString, int>> sortedEntries = ages.toVector();
std::sort(sortedEntries.begin(), sortedEntries.end(), [](const QPair<QString, int>& a, const QPair<QString, int>& b) {
return a.second < b.second; // по возрасту по возрастанию
});
for (const auto& pair : sortedEntries) {
qDebug() << pair.first << pair.second;
}
Пример вывода:
Bob 25
Alice 30
Charlie 35
// Можно создать новый QMap, если нужна именно карта:
QMap<QString, int> sortedMap;
for (const auto& pair : sortedEntries)
sortedMap.insert(pair.first, pair.second)
Сортировка QSet
QSet — это множество уникальных значений, которое не гарантирует порядка при обходе, несмотря на то, что элементы могут быть выведены в определённом (но нестабильном) порядке.
QSet<QString> names = {"Charlie", "Alice", "Bob"};
Цель: отсортировать и вывести в алфавитном или другом порядке
Решение:
- Преобразуем
QSetвQVector - Сортируем с помощью
std::sort
QVector<QString> sortedNames = names.values(); // или toList()
std::sort(sortedNames.begin(), sortedNames.end());
for (const auto& name : sortedNames)
qDebug() << name;
Результат:
Alice Bob Charlie /// Сортировка по убыванию: std::sort(sortedNames.begin(), sortedNames.end(), std::greater<QString>());
| Контейнер | По умолчанию сортировка | Сортировка по значению вручную | Совместимость со std::sort |
|---|---|---|---|
QMap | По ключу | Да (через QVector<QPair>) | Да |
QSet | Нет | Да (через QVector) | Да |
Рекомендации:
- Для пользовательской сортировки используйте
QVectorкак промежуточный контейнер. - При необходимости повторного использования создавайте обёртку-функцию для сортировки.
- Не стоит пытаться переопределять поведение
QMapилиQSetнапрямую — они неизменно ориентированы на ключ/значение в фиксированном порядке.
