2011-12-13 21 views
45

unordered_mapからのキーと値のリスト(vector)を取得する最も効率的な方法は何ですか?unordered_mapからのキーと値のリストの取得

具体的には、問題のマップがunordered_map<string, double>であるとします。 私はvector<string>のようなキーとvector<double>という値を取得したいと思います。

unordered_map<string, double> um; 

vector<string> vs = um.enum_keys(); 
vector<double> vd = um.enum_values(); 

私はちょうどマップ全体で反復し、結果を収集し、より多くの 効率的な方法はありますか?私はそれに切り替えるかもしれないので、通常のマップ、 のためにも働くメソッドを持っていることはいいでしょう。

+0

、私はあなたが望む結果を得るための簡単な方法が表示されていないが、私は何かが欠けていてもよいです。 'std :: vector > v(map.begin()、map.end());と言うことができます。キーと値のペアのベクトルを与える必要があります。 –

+0

@ keith.layne:私はキーと値のために別々のベクトルを探しています。 –

+0

私が言ったように、それには何も組み込まれていません。下記参照。 –

答えて

47

さて、ここであなたが行きます。あなたは2つのコンテナで操作しているので、実際にその事実を隠すことのできるSTLの魔法はありません。

Louisが言ったように、これはSTL mapまたはsetコンテナのいずれでも動作します。使用

+1

オクラホマ、地図上で反復するよりも良いことはないと思う。私は使用している構文を認識しません。 '(auto kv:map)'とは何を表しますか?私は、地図の要素上の反復(つまり、ループ)が予想されていました。 –

+1

@FaheemMithaこれは新しいC++ 11 forループです。それはまるでそれがそうであるように見えるし、 'auto'と組み合わされて、物事を少しきちんと整えます。 'auto'は、kvの型を明示的に書く必要がなくなります。本質的に同じことを達成するには、iteratorのforループ、lambdaのfor_eachなどがあります。あなたが 'unordered_map'を述べたので、私はC++ 11を使用していると仮定しました。 –

+0

私はそうだと思いますが、私は本当に新しい標準に慣れていません。ありがとう。 –

2

STLには、マップからすべてのキーまたは値を取得する組み込みメソッドはありません。

順序付けされていないマップや規則マップを反復処理する方法はありません。最善の方法は、反復してキーまたは値をベクターに収集することです。

テンプレート関数を作成して、あらゆる種類のマップを反復することができます。

std::vector<Key> keys; 
keys.reserve(map.size()); 
std::vector<Val> vals; 
vals.reserve(map.size()); 

for(auto kv : map) { 
    keys.push_back(kv.first); 
    vals.push_back(kv.second); 
} 

効率はおそらく改善することができるが、そこにある:

6

C++ - 14あなたも行うことができ、次の(完全なソースが含まれているように編集):私は、次のコマンドでこれをコンパイル

#include <algorithm> 
#include <iostream> 
#include <string> 
#include <unordered_map> 
#include <vector> 

using namespace std; 

typedef string Key; 
typedef int Value; 

auto key_selector = [](auto pair){return pair.first;}; 
auto value_selector = [](auto pair){return pair.second;}; 

int main(int argc, char** argv) { 
    // Create a test map 
    unordered_map<Key, Value> map; 
    map["Eight"] = 8; 
    map["Ten"] = 10; 
    map["Eleven"] = 11; 

    // Vectors to hold keys and values 
    vector<Key> keys(map.size()); 
    vector<Value> values(map.size()); 

    // This is the crucial bit: Transform map to list of keys (or values) 
    transform(map.begin(), map.end(), keys.begin(), key_selector); 
    transform(map.begin(), map.end(), values.begin(), value_selector); 

    // Make sure this worked: Print out vectors 
    for (Key key : keys) cout << "Key: " << key << endl; 
    for (Value value : values) cout << "Value: " << value << endl; 

    return 0; 
} 

g++ keyval.cpp -std=c++14 -o keyval 

テストは、それが鍵を印刷し、期待どおりの値。

+0

これはもっと説明できます – Whitecat

+0

コンパイルできる自己完結型のサンプルを書くことができますか?また、使用するコンパイラについて言及し、それをコンパイルするために使用するコマンドラインを提供すれば、それは役に立ちます。ありがとう。 –

+0

また、ここで 'Key'と' Value'と 'um'とは何ですか?あなたはそれらを定義していません。おそらくあなたは質問からの定義、つまり "unordered_map um;"を使用していますが、その場合は関係なく、ここで再度言及する必要があります。 –

0

後で参加しましたが、これが誰かにとって参考になると思っていました。
key_typemapped_typeを使用する2つのテンプレート関数。

namespace mapExt 
{ 
    template<typename myMap> 
    std::vector<typename myMap::key_type> Keys(const myMap& m) 
    { 
     std::vector<typename myMap::key_type> r; 
     r.reserve(m.size()); 
     for (const auto&kvp : m) 
     { 
      r.push_back(kvp.first); 
     } 
     return r; 
    } 

    template<typename myMap> 
    std::vector<typename myMap::mapped_type> Values(const myMap& m) 
    { 
     std::vector<typename myMap::mapped_type> r; 
     r.reserve(m.size()); 
     for (const auto&kvp : m) 
     { 
      r.push_back(kvp.second); 
     } 
     return r; 
    } 
} 

使用法:ドラフト規格を見ると

std::map<long, char> mO; 
std::unordered_map<long, char> mU; 
// set up the maps 
std::vector<long> kO = mapExt::Keys(mO); 
std::vector<long> kU = mapExt::Keys(mU); 
std::vector<char> vO = mapExt::Values(mO); 
std::vector<char> vU = mapExt::Values(mU); 
関連する問題