簡體   English   中英

如何排序QMap <QString, myStruct> ?

[英]How to sort QMap<QString, myStruct>?

我有一個QMap<QString, myStruct>

myStruct {
    QString firstname;
    QString lastname;
    QString status;
}

如何根據優先級順序對此QMap進行排序: status然后是firstname然后是lastname

據我所知,你想檢索以上述方式排序的地圖值,但仍然可以訪問密鑰。 對?

快說,地圖是一個集<key, value>對通過自動排序,那么你可以嘗試的列表<value, key>對通過價值人工分揀代替。 類似於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;
}

當然,它是一次性使用結構,不會與原始地圖保持更新,但你提到地圖是固定的 (常量?)所以它可能不是問題。

順便說一下, QMap可用於反向查找,但僅在myStruct部分的值也是唯一的情況下(因此它們也可以用作鍵),否則您可能在構造逆映射時覆蓋值。

注意: std::tie僅用於簡化元組的排序條件(因此您需要包含<tuple> )。

UPDATE

回答你的一條評論:是的,你也可以指定你自己的比較謂詞,然后避免覆蓋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);
});

當然,您可以根據需要實現比較lambda,我再次使用std::tie來簡化帖子中的邏輯。 缺點是如果你需要在幾個地方生成逆映射,你必須在任何地方重復lambda表達式(或者創建一個函數來創建逆映射)。

作為旁注,如果你好奇, lhsrhs左手側右手側 ,在這種情況下,它們被排序算法用作lhs < rhs用於比較元素。

最后,如果你想避免使用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
}

您無法手動對QMap排序,您必須使用QList (或QVector )並在其上使用std::sort 使用QMap::values()將映射中的值(結構)提取到列表中,然后實現比較函數/方法並使用std::sort調用它。 有關如何執行此操作的一些提示,請參閱cbuchart的答案。

在值更改時保持地圖和列表同步是一個不同的問題,如果這是一個要求,您應該創建一個單獨的問題,添加MCVE以及您嘗試的更多詳細信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM