📘

c++ 複数条件でsort

2022/09/25に公開

sort関数に比較関数を使うわけですが、このときに複数のkeyで比較する書き方をメモしておきます。
(ネットで調べてみると、1つのkeyでsortする例が多く、わかりにくかったため。)

[id, 名前, 得点]のような項目のデータを、
「"名前"の昇順、"得点"の降順でsortする」場合を、例にします。

1.考え方

テストデータを以下のように準備しました。

    vector<tuple<int, string, int>> data = {
        {1, "tokyo", 10},
        {2, "osaka", 30},
        {3, "tokyo", 50},
        {4, "tokyo", 30},
        {5, "osaka", 10},
    };

これを、「"名前"の昇順、"得点"の降順でsortする」場合、Compare関数は以下のようになります。

    function cmp = [](const tuple<int, string, int> &x, const tuple<int, string, int> &y) -> bool {
        if (get<1>(x) != get<1>(y)) {
            return get<1>(x) < get<1>(y);  // nameを昇順に。
        } else {
            return get<2>(x) > get<2>(y);  // pointを降順に。
        }
    };

2.code

#include <iostream>
#include <vector>
#include <functional>
using namespace std;


int main() {
    // data: {{id, name, point}} 
    vector<tuple<int, string, int>> data = {
        {1, "tokyo", 10},
        {2, "osaka", 30},
        {3, "tokyo", 50},
        {4, "tokyo", 30},
        {5, "osaka", 10},
    };

    function cmp = [](const tuple<int, string, int> &x, const tuple<int, string, int> &y) -> bool {
        if (get<1>(x) != get<1>(y)) {
            return get<1>(x) < get<1>(y);  // nameを昇順に。
        } else {
            return get<2>(x) > get<2>(y);  // pointを降順に。
        }
    };

    sort(data.begin(), data.end(), cmp);
    for (int i = 0; i < data.size(); i++) {
        printf("id:%d, name:%s, point:%d\n", get<0>(data[i]), get<1>(data[i]).c_str(), get<2>(data[i]));
    }
    // 出力結果
    // id:2, name:osaka, point:30
    // id:5, name:osaka, point:10
    // id:3, name:tokyo, point:50
    // id:4, name:tokyo, point:30
    // id:1, name:tokyo, point:10
}

Discussion