2015-12-29 15 views
12

anahtar içerip içermediğinin kontrol edilmesi.basit yöntemi unordered_maps arasında unordered_map I "çok önemli" sözdizimi kullanılarak bir eleman referans alabilir, öyle ki unordered_maps bir unordered_map kullanıyorum

Bir öğeye erişmeye çalışmadan önce bir öğenin var olup olmadığını kontrol etmek için aynı "çoklu anahtar" sözdizimini kullanmanın kullanışlı bir yolu var mı? Değilse, en basit yol nedir? niyetinizi anahtarın varlığını sınamak için ise operator[] zaten yoksa, bu anahtarın yeni bir değer oluşturmak varsayılan çünkü

cevap

15

, ben

my_map[k1][k2] 

kullanmak ister.

Daha ziyade std::unordered_map::find kullanmayı tercih ederim. Eğer ilk anahtar var belli, ama hem anahtarlarının varlığını denetler bir işlev yapmak isterseniz değil ikinci Eğer

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

yapabileceğini Yani eğer, o zaman

gibi bir şey yazabilirsiniz
//------------------------------------------------------------------------------ 
/// \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

Ve değilseniz k1'in var olduğundan emin olmak için, 'find'ı iki kez kullanmak istersiniz - bir kez k1'i kontrol etmek için ve bir kez k2'yi kontrol etmek için. – zmb

+0

@zmb Bence ihtiyacım olan şey bu. – user997112

+0

@ user997112 Bu durumda cevabın alt kısmında 'nested_key_exists' işlevini kullanabilirsiniz. Her iki anahtar da "yanlış" ise, aksi takdirde "true" döner. – CoryKramer

0

Ben kontrol etmek için bir çok anahtar sözdizimi vardır inanmıyorum, ama en basit yolu find yöntemi kullanmak olacaktır. Sen

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

her değerli ilişkisel kap için çalışacak bir unordered_map s unordered_map ait uygulamak için basit işlevi yazabilirsiniz. içerdiği k1 öğesinden bir öğe olduğu doğrudur.

1

Böyle bir şey mi var? (Değişebilir durum için)

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

şöyle seslendi:

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 
} 

... ya da daha fazla piton benzeri yolu yok ...

try { 
    auto& v = my_map.at(k1).at(k2); 
    // use v 
} 
catch(const std::out_of_range & e) { 
    // didn't find it 
} 
İlgili konular