2011-12-13 15 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

ठीक है, तुम जाओ:

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

क्षमता शायद सुधार किया जा सकता है, लेकिन वहाँ यह है। हालांकि आप दो कंटेनर पर काम कर रहे हैं, इसलिए वास्तव में कोई भी एसटीएल जादू नहीं है जो उस तथ्य को छुपा सकता है।

लुई ने कहा, यह किसी भी एसटीएल map या set कंटेनर के लिए काम करेगा।

+1

ठीक है, एसओ मुझे लगता है कि मानचित्र पर फिर से शुरू करने से बेहतर कुछ भी नहीं है। मैं आपके द्वारा उपयोग किए जा रहे वाक्यविन्यास को नहीं पहचानता हूं। '(ऑटो केवी: मानचित्र) 'क्या इंगित करता है। मैं मानचित्र के तत्वों पर केवल एक पुनरावृत्ति (यानी लूप के लिए) की अपेक्षा करता। –

+1

@ फेहेम मिथा यह लूप के लिए नया सी ++ 11 है। यह वही करता है जो ऐसा लगता है, और 'ऑटो' के साथ संयुक्त चीजों को थोड़ा और साफ बनाता है। 'ऑटो' आपको केवी के प्रकार को स्पष्ट रूप से लिखने से बचाता है। अनिवार्य रूप से एक ही चीज को पूरा करने के कई तरीके हैं, जिसमें इटेटरेटर्स के लिए लूप, 'labda के साथ' for_each 'शामिल है। चूंकि आपने' unordered_map' का उल्लेख किया है, मुझे लगता है कि आप C++ 11 का उपयोग कर रहे थे। –

+0

मुझे लगता है कि मैं हूं, लेकिन मैं वास्तव में नए मानक के साथ familar नहीं हूँ। धन्यवाद। –

2

एसटीएल में मानचित्र से सभी चाबियाँ या मूल्य प्राप्त करने के लिए कोई अंतर्निहित विधि नहीं है।

एक अनियंत्रित मानचित्र या नियमित मानचित्र को फिर से शुरू करने के लिए कोई अलग नहीं है, सबसे अच्छा तरीका यह है कि इसे पुन: स्थापित करें और वेक्टर को कुंजी या मूल्य एकत्र करें।

आप किसी भी प्रकार के मानचित्र को फिर से शुरू करने के लिए एक टेम्पलेट फ़ंक्शन लिख सकते हैं।

6

का उपयोग सी ++ - 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

इसके अलावा, यहां 'कुंजी' और 'मान' और' um' क्या हैं? आपने उन्हें परिभाषित नहीं किया है। शायद आप प्रश्न से परिभाषा का उपयोग कर रहे हैं, अर्थात् "unordered_map um;", लेकिन उस स्थिति में, आपको इसका उल्लेख करना चाहिए, भले ही। –

0

देर से जुड़ना, लेकिन सोचा कि यह किसी के लिए सहायक हो सकता है।
key_type और 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; 
    } 
} 

उपयोग:

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); 
संबंधित मुद्दे