2015-12-29 6 views
12

मैं unordered_maps के unordered_map उपयोग कर रहा हूँ, मैं एक तत्व "बहु कुंजी" सिंटैक्स का उपयोग संदर्भित कर सकते हैं जैसे कि:सरलतम विधि की जाँच करने के unordered_maps की unordered_map कुंजी है कि क्या

my_map[k1][k2]

क्या यह देखने के लिए एक "बहु-कुंजी" वाक्यविन्यास का उपयोग करने का कोई सुविधाजनक तरीका है कि यह जांचने से पहले कोई तत्व मौजूद है या नहीं? यदि नहीं, तो सबसे आसान तरीका क्या है?

उत्तर

15

आपका इरादा कुंजी के अस्तित्व के लिए परीक्षण करने के लिए है, तो मैं

my_map[k1][k2] 

का उपयोग नहीं करेंगे क्योंकि operator[] डिफ़ॉल्ट अगर यह पहले से मौजूद नहीं है कि कुंजी के लिए एक नया मूल्य का निर्माण करेगी।

बल्कि मैं std::unordered_map::find का उपयोग करना पसंद करूंगा। तो अगर आप कुछ पहले कुंजी मौजूद हैं, लेकिन दूसरा नहीं आप

if (my_map[k1].find(k2) != my_map[k1].end()) 
{ 
    // k2 exists in unordered_map for key k1 
} 

कर सकता है आप एक समारोह है कि दोनों कुंजी के अस्तित्व के लिए जाँच करता है बनाने के लिए चाहते हैं, तो आप

की तरह कुछ लिख सकता है
//------------------------------------------------------------------------------ 
/// \brief Determines a nested map contains two keys (the outer containing the inner) 
/// \param[in] data Outer-most map 
/// \param[in] a Key used to find the inner map 
/// \param[in] b Key used to find the value within the inner map 
/// \return True if both keys exist, false otherwise 
//------------------------------------------------------------------------------ 
template <class key_t, class value_t> 
bool nested_key_exists(std::unordered_map<key_t, std::unordered_map<key_t, value_t>> const& data, key_t const a, key_t const b) 
{ 
    auto itInner = data.find(a); 
    if (itInner != data.end()) 
    { 
     return itInner->second.find(b) != itInner->second.end(); 
    } 
    return false; 
} 
+1

और अगर आप नहीं कर रहे हैं निश्चित है कि 'k1' मौजूद है, आप 'find' का उपयोग दो बार करना चाहते हैं - एक बार' k1' की जांच करने के लिए और एक बार 'k2' की जांच करने के लिए। – zmb

+0

@zmb मुझे लगता है कि मुझे यही चाहिए। – user997112

+0

@ user997112 उस स्थिति में आप उत्तर के निचले भाग में 'nested_key_exists' फ़ंक्शन का उपयोग कर सकते हैं। यदि दोनों कुंजी मौजूद हैं, तो यह 'सत्य' वापस आ जाएगी, अन्यथा। – CoryKramer

0

मुझे विश्वास नहीं है कि जांच करने के लिए एक बहु-कुंजी वाक्यविन्यास है, लेकिन सबसे आसान तरीका find विधि का उपयोग करना होगा। आप एक साधारण समारोह लिखने unordered_map की एक unordered_map

reference

3
template<class M> 
bool contains(M const&){return true;} 
template<class M, class K, class...Ks> 
bool contains(M const&m, K const&k, Ks const&...ks){ 
    auto it=m.find(k); 
    if (it==m.end()) return false; 
    return contains(it->second, ks...); 
} 

हर एक-मान साहचर्य कंटेनर के लिए काम करेंगे करने के लिए इसे लागू करने के लिए कर सकता है।

contains(my_map, k1, k2) सत्य है अगर वहाँ कोई तत्व k1 है जिसमें k2 है।

1

ऐसा कुछ? (परिवर्तनशील मामले के लिए)

using inner_map = std::map<key_type, value_type>; 
using outer_map = std::map<key_type, inner_map> 

boost::optional<value_type&> 
element_for_keys(outer_map& map, const key_type& k1, const key_type& k2) 
{ 
    auto it_outer = map.find(k1); 
    if (it_outer = map.end()) 
    return {}; 
    auto &map2 = it_outer->second; 
    auto it_inner = map2.find(k2); 
    if (it_inner == map2.end()) 
    return {}; 

    return { it_inner->second }; 
} 

तो जैसे कहा जाता है:

auto op_value = element_for_keys(my_map, kv1, kv2); 
if (op_value) { 
    // use op_value.value() 
} 
else { 
    // handle case where it does not exist 
} 

... या वहाँ अधिक अजगर की तरह जिस तरह से है ...

try { 
    auto& v = my_map.at(k1).at(k2); 
    // use v 
} 
catch(const std::out_of_range & e) { 
    // didn't find it 
} 
संबंधित मुद्दे