【问题标题】:How to sort list with multiple sort keys如何使用多个排序键对列表进行排序
【发布时间】:2011-12-12 04:27:30
【问题描述】:

我正在使用比较函数对 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 一起工作正常。 但我需要使用多个 attr 排序的列表。比如'按姓氏排序,然后按年龄,然后按性别'

我需要一个排序函数来按多个 sortKey 排序(这不起作用!)

我们如何使用多个排序键进行排序? 是否有任何可用的数据结构支持这一点? (就像地图总是根据给定的键排序)

【问题讨论】:

  • 您不能对哈希表进行排序,也不能对它的子范围进行排序。我不知道QHash到底是如何实现的,但你的请求似乎不是一个有意义的操作,实际上h.values(val)应该返回一个const并且不能被分配的东西。

标签: c++ qt sorting stl hash


【解决方案1】:

只需以逻辑方式定义谓词,使用主键进行比较,并在主键不确定时使用次键作为后备:

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 );

【讨论】:

  • 这个解决方案很简单。如果我们有 n 个键怎么办?
  • @smitpatel24:那么你需要更多 if's。这意味着迭代排序键列表,最好通过递归。添加了一个 sn-p。
  • @thiton 只有少数几件事是“最好的递归”完成的,这个简单的 for 循环肯定不是其中之一。
【解决方案2】:

您可以使用 std::tuple(或旧 C++03 的 boost::tuple)在一行中进行此比较:

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

【讨论】:

  • 在我的情况下,键的数量会有所不同,所以这可能不是一个好主意。但仍然是最简单的解决方案。 :)
猜你喜欢
  • 2017-09-09
  • 2010-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多