web-dev-qa-db-ja.com

mapにキーの値が含まれているかどうかを確認しますか?

STLマップに特定のキーの値が含まれているかどうかを判断するための最良の方法は何ですか?

#include <map>

using namespace std;

struct Bar
{
    int i;
};

int main()
{
    map<int, Bar> m;
    Bar b = {0};
    Bar b1 = {1};

    m[0] = b;
    m[1] = b1;

    //Bar b2 = m[2];
    map<int, Bar>::iterator iter = m.find(2);
    Bar b3 = iter->second;

}

これをデバッガで調べると、iterは単なるゴミデータに見えます。

この行のコメントを外した場合:

Bar b2 = m[2]

デバッガはb2{i = 0}であることを示しています。 (未定義のインデックスを使用すると、すべての空の値または初期化されていない値を含む構造体が返されることになります)

どちらの方法もそれほど素晴らしいものではありません。私が本当に欲しいのはこのようなインターフェースです。

bool getValue(int key, Bar& out)
{
    if (map contains value for key)
    {
        out = map[key];
        return true;
    }
    return false;
}

これらの線に沿って何かが存在しますか?

212
Nick Heiner

これらの線に沿って何かが存在しますか?

いいえ。stlマップクラスでは、マップを検索し、返されたイテレータを::find()と比較するために std::map::end() を使用します。

そう

map<int,Bar>::iterator it = m.find('2');
Bar b3;
if(it != m.end())
{
   //element found;
   b3 = it->second;
}

明らかにあなたが望むならあなた自身のgetValue()ルーチンを書くこともできます(C++でもoutを使う理由はありません)、std::map::find()を使うことにハングしたら、時間を無駄にしたくないと思うでしょう。

またあなたのコードは少し間違っています:

m.find('2');はマップから'2'であるキー値を探します。 IIRCでは、C++コンパイラは暗黙的に '2'をintに変換します。その結果、 '2'のASCIIコードの数値が必要になります。

この例のあなたのキータイプはintなので、あなたはこのように検索したいです:m.find(2);

230
Alan

マップがマルチマップではない限り、最も洗練された方法の1つはcountメソッドを使用することです。

if (m.count(key))
    // key exists

要素が実際にマップに存在する場合、カウントは1になります。

289
pconnell

その正確な構文ではなくfindだけですでに存在します。

if (m.find(2) == m.end() )
{
    // key 2 doesn't exist
}

値にアクセスしたい場合は、次のようにします。

map<int, Bar>::iterator iter = m.find(2);
if (iter != m.end() )
{
    // key 2 exists, do something with iter->second (the value)
}

C++ 0xとautoでは、構文はもっと単純です。

auto iter = m.find(2);
if (iter != m.end() )
{
    // key 2 exists, do something with iter->second (the value)
}

単純化するための新しいメカニズムを考え出すのではなく、慣れることをお勧めします。あなたは少しコードを減らすことができるかもしれませんが、それをすることのコストを考慮してください。今、あなたはC++に精通している人々が認識することができない新しい機能を導入しました。

これらの警告にもかかわらずこれをとにかく実装したいと思う場合それから:

template <class Key, class Value, class Comparator, class Alloc>
bool getValue(const std::map<Key, Value, Comparator, Alloc>& my_map, int key, Value& out)
{
    typename std::map<Key, Value, Comparator, Alloc>::const_iterator it = my_map.find(key);
    if (it != my_map.end() )
    {
        out = it->second;
        return true;
    }
    return false;
}
49
stinky472

C++ 2 とすれば、次のようになります。

std::map::contains( const Key& key ) const;

Mapがキーkeyを持つ要素を保持している場合、それはtrueを返します。

18
kebs

amap.findは、探しているものが見つからない場合はamap::endを返します - あなたはそれをチェックすることになっています。

7
Alex Martelli

findの戻り値をendと照合してください。

map<int, Bar>::iterator it = m.find('2');
if ( m.end() != it ) { 
  // contains
  ...
}
4
JaredPar

他のいくつかの答えを簡潔に要約すると、

まだC++ 20を使っていない場合は、独自のmapContainsKey関数を書くことができます。

bool mapContainsKey(std::map<int, int> map, int key)
{
  if (map.find(key) == map.end()) return false;
  return true;
}

mapunordered_map、およびさまざまなキーと値の型に対する多くのオーバーロードを避けたい場合は、これをtemplate関数にすることができます。

C++ 20以降を使用している場合は、組み込みのcontains関数があります。

std::map<int, int> myMap;

// do stuff with myMap here

int key = 123;

if (myMap.contains(key))
{
  // stuff here
}
1
cdahms

次のコードを使ってgetValue関数を作成できます。

bool getValue(const std::map<int, Bar>& input, int key, Bar& out)
{
   std::map<int, Bar>::iterator foundIter = input.find(key);
   if (foundIter != input.end())
   {
      out = foundIter->second;
      return true;
   }
   return false;
}
1
Kip Streithorst

マップにキーがあるかどうかを判断したい場合は、mapのfind()またはcount()メンバー関数を使用できます。この例で使用されているfind関数は、イテレータをelementまたはmap :: endに返します。 countの場合、countは見つかった場合1を返し、そうでなければゼロを返します(そうでなければ)。

if(phone.count(key))
{ //key found
}
else
{//key not found
}

for(int i=0;i<v.size();i++){
    phoneMap::iterator itr=phone.find(v[i]);//I have used a vector in this example to check through map you cal receive a value using at() e.g: map.at(key);
    if(itr!=phone.end())
        cout<<v[i]<<"="<<itr->second<<endl;
    else
        cout<<"Not found"<<endl;
}
0