Obtaining list of keys and values from unordered_map

后端 未结 4 1648
陌清茗
陌清茗 2020-12-13 08:22

What is the most efficient way of obtaining lists (as a vector) of the keys and values from an unordered_map?

For concreteness, suppose the

相关标签:
4条回答
  • 2020-12-13 08:34

    Using C++-14 you could also do the following (edited to contain 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 it printed the keys and values as expected.

    0 讨论(0)
  • 2020-12-13 08:53

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

    There is no different to iterate a unordered map or regular map, the best way is to iterate it and collect key or value to a vector.

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

    0 讨论(0)
  • 2020-12-13 08:57

    Joining late, but thought this might be helpful to someone.
    Two template functions making use of 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;
        }
    }
    

    Usage:

    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 讨论(0)
  • 2020-12-13 08:59

    Okay, 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 there it is. You're operating on two containers though, so there's not really any STL magic that can hide that fact.

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

    0 讨论(0)
提交回复
热议问题