unordered_set unordered_map example c++ vector c++11 std unordered-map

c++ - example - Obtención de una lista de claves y valores de unordered_map



unordered_map example (4)

De acuerdo, aquí tienes:

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

La eficiencia probablemente puede mejorarse, pero ahí está. Sin embargo, estás operando en dos contenedores, por lo que no hay ninguna magia de STL que pueda ocultar ese hecho.

Como dijo Louis, esto funcionará para cualquiera de los map STL o para set contenedores.

¿Cuál es la forma más eficiente de obtener listas (como un vector ) de las claves y valores de un unordered_map ?

Para ser más concretos, supongamos que el mapa en cuestión es unordered_map<string, double> . Entonces me gustaría obtener las claves como un vector<string> y los valores como un vector<double> .

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

Puedo iterar por el mapa y recoger el resultado, pero ¿hay un método más eficiente? Sería bueno tener un método que también funciona para el mapa regular, ya que podría cambiar a eso.


En STL no hay un método incorporado para obtener todas las claves o valores de un mapa.

No hay diferencia para iterar un mapa desordenado o un mapa normal, la mejor manera es iterarlo y recopilar la clave o el valor de un vector.

Puede escribir una función de plantilla para iterar cualquier tipo de mapa.


Se unió tarde, pero pensó que esto podría ser útil para alguien.
Dos funciones de plantilla haciendo uso de key_type y 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; } }

Uso:

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


Usando C ++ - 14 también podría hacer lo siguiente (editado para contener fuente completa):

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

Compilé esto con el siguiente comando:

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

Al probarlo, se imprimieron las claves y los valores como se esperaba.