Retrieving a list of keys and values ​​from unordered_map

What is the most efficient way to get lists (like vector ) of keys and values ​​from unordered_map ?

For concreteness, suppose that the map in question is a unordered_map<string, double> . I would like to get the keys as vector<string> , and the values ​​as vector<double> .

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

I can just iterate over the map and collect the result, but is there still an effective method? It would be nice to have a method that also works for a regular card, since I can switch to this.

+44
c ++ unordered-map vector c ++ 11 std
Dec 13 '11 at 3:28
source share
4 answers

Ok, here you go:

 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); } 

Efficiency can probably be improved, but it is. You work on two containers, although in reality there is no STL magic that can hide this fact.

As Louis said, this will work for any STL map or set containers.

+45
Dec 13 2018-11-11T00:
source share

Using C ++ - 14, you can also do the following (edited for the full source):

 #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; } 

I compiled this with the following command:

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

Testing printed keys and values ​​as expected.

+6
Nov 19 '15 at 2:20
source share

There is no built-in method in STL to get all keys or values ​​from a map.

It is impossible to iterate over an unordered card or a regular card; the best way is to iterate over it and collect the key or value for the vector.

You can write a template function to iterate any kind of map.

+2
Dec 13
source share

Entry is late, but thought it might help someone.
Two template functions use key_type and mapped_type .

 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; } } 

Using:

 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); 
0
Nov 26 '15 at 15:00
source share



All Articles