Как отсортировать список с несколькими ключами сортировки - PullRequest
2 голосов
/ 12 декабря 2011

Я использую функцию сравнения для сортировки QList и MyClass имеет n различных атрибутов, таких как адрес, возраст, имя, фамилия и т. д.

SortKey - это что-то вроде этого.

typedef QPair<QString, Qt::SortOrder> SortKeyPair;         
//pair of attr name (i.e. gender and order of sorting asc|desc)


static bool compare( MyClass *o1, MyClass *o2)
{
    //sortKey is global static var.
    if (sortKey.second == Qt::AscendingOrder) {
        if (o1->dataField(sortKey.first) < o2->dataField(sortKey.first)) return true;
        else return false;
    } else {
        if (o1->dataField(sortKey.first) > o2->dataField(sortKey.first)) return true;
        else return false;
    }
    return false;
}

Сортировка по одному атрибуту. отлично работает с qSort. Но мне нужен список, отсортированный по нескольким атрибутам. как «сортировка по фамилии, затем по возрасту, затем по полу»

Мне нужна функция сортировки для сортировки по нескольким sortKey (что не работает!)

Как мы можем сортировать с несколькими ключами сортировки? Есть ли какая-либо структура данных, которая поддерживает это? (как карта всегда хранит вещи в соответствии с данным ключом)

Ответы [ 2 ]

3 голосов
/ 12 декабря 2011

Просто определите свой предикат логическим путем, используя основной ключ для сравнения и используя вспомогательный ключ в качестве запасного варианта, когда основной неокончательный:

if (o1->dataField( firstSortKey ) < o2->dataField( firstSortKey ))
    return true;
else if (o1->dataField( firstSortKey) > o2->dataField( firstSortKey ))
    return false;
else if ( o1->dataField( secondSortKey ) < o2->dataField( secondSortKey ) )
    return true;
else
    return false;

или, для общего случая:

bool compare_on( int key_index, ...) {
  if (o1->dataField( key[key_index] ) < o2->dataField( key[key_index] ))
    return true;
  else if (o1->dataField( key[key_index] ) > o2->dataField( key[key_index] ))
    return false;
  else if ( key_index == max_key_index )
    return false;
  else
    return compare_on( key_index + 1 );
1 голос
/ 13 декабря 2011

Вы можете использовать std :: tuple (или boost :: tuple для более старого C ++ 03), чтобы выполнить это сравнение в одной строке:

return make_tuple(a.lastname, a.age, a.gender) < make_tuple(b.lastname, b.age, b.gender);
...