Как отсортировать QMap и QSet в Qt: практическое руководство

Автор: | 12 июня, 2025

Контейнеры 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 по умолчанию сортируется по ключу, для сортировки по значению нужно:

  1. Преобразовать данные в QVector<QPair<QString, int>>
  2. Отсортировать вектор
  3. Использовать результат по необходимости
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"};

Цель: отсортировать и вывести в алфавитном или другом порядке

Решение:

  1. Преобразуем QSet в QVector
  2. Сортируем с помощью 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 напрямую — они неизменно ориентированы на ключ/значение в фиксированном порядке.