unordered_map
からキーと値のリストを(vector
として)取得する最も効率的な方法は何ですか?
具体的には、問題のマップが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();
マップ全体を反復処理して結果を収集できますが、より効率的な方法はありますか?私はそれに切り替えるかもしれないので、通常のマップでも機能するメソッドがあるといいでしょう。
さて、ここに行きます:
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);
}
効率はおそらく改善できますが、改善されています。ただし、2つのコンテナを操作しているため、その事実を隠すことができるSTLマジックは実際にはありません。
Louisが言ったように、これはSTL map
またはset
コンテナのいずれでも機能します。
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
それをテストすると、期待どおりにキーと値が印刷されました。
STLには、マップからすべてのキーまたは値を取得する組み込みメソッドはありません。
順序付けられていないマップまたは通常のマップを繰り返すことには違いはありません。最善の方法は、それを繰り返して、キーまたは値をベクトルに収集することです。
テンプレート関数を作成して、あらゆる種類のマップを反復処理できます。
遅く参加したが、これは誰かに役立つかもしれないと思った。key_type
およびmapped_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);