質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.19%

std::mapの文字列キーを格納したstd::vectorをソートする

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 3,623

前提・実現したいこと

文字列のキーと構造体の値を持つstd::mapとキーを格納したstd::vectorがあり、std::mapのキーに対応する値の1つのメンバ変数をもとにキーを格納したstd::vectorをソートしたい。

コード

#include <vector>
#include <map>
#include <string>
#include <algorithm>

using namespace std;

struct Person
{
    string name;
    unsigned int age;
};

int main()
{
    //値はすでに格納されているものとする
    map<string, Person> person_map;
    vector<string> person_key;

    //sortobjectの部分をどうするか?
    sort(person_key.begin(), person_key.end(), sortobject);

    //最も若い人物の名前を表示する
    cout << person_map[person_key[0]].name.c_str() << '(' << person_map[person_key[0]].age << ')' << endl;

    return 0;
}

補足情報(言語/FW/ツール等のバージョンなど)

Visual Studio Community 2017を使用。言語はC++。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

person_keyにperson_mapのキーの一部が入っていて、そのキーをageの小さい順に並び変えたいってことですね?
こんな感じでしょうか。

sort(person_key.begin(), person_key.end(), [&](const auto& lhs, const auto& rhs) {
    const auto& lv = person_map[lhs];
    const auto& rv = person_map[rhs];
    if (lv.age == rv.age) {
        return lv.name.compare(rv.name) < 0;
    }
    return lv.age < rv.age;
});


ラムダ式の[&]でperson_mapを参照キャプチャしておくのがポイントです。
(=でもいいけどコピーしちゃうので)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

二度手間感がすごいですが、こんな感じでしょうか。

#include <array>
#include <vector>
#include <map>
#include <string>

#include <algorithm>
#include <iostream>

struct Person {
    std::string name;
    unsigned int age;
};

int main(void) {
    //
    // Prepare data
    std::array<Person, 4> arr{
        {{"Yamada", 25u}, {"Suzuki", 63u}, {"Tanaka", 35u}, {"Takahashi", 18u}}
    };

    std::vector<std::string> person_key; person_key.reserve(arr.size());
    std::map<std::string, Person> person_map;
    for(auto&& elem: arr) {
        person_key.emplace_back(elem.name);
        person_map[elem.name] = std::move(elem);
    }

    //
    // Sort
    auto compare = [&person_map](const std::string& p1, const std::string& p2) {
         return person_map[p1].age < person_map[p2].age;
    };
    std::sort(person_key.begin(), person_key.end(), compare);

    for(const auto& elem: person_key) {
        std::cout << person_map[elem].age << ": " << elem << "\n";
    } 
    std::cout << std::endl;

    return 0;
}

出力

18: Takahashi
25: Yamada
35: Tanaka
63: Suzuki

やっぱC++難しいですね...
おそらく良くない点があると思います、ご指摘をいただけると幸いです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.19%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる