STLマップを横断したい。キーを使いたくありません。順序は気にせず、含まれるすべての要素にアクセスする方法を探しています。これどうやってするの?
はい、標準ライブラリmap
を横断できます。これは、map
をトラバースするために使用される基本的な方法であり、標準ライブラリコレクションをトラバースするためのガイダンスとして機能します。
#include <cstdlib>
#include <map>
#include <string>
using namespace std;
int main()
{
typedef map<int,string> MyMap;
MyMap my_map;
// ... magic
for( MyMap::const_iterator it = my_map.begin(); it != my_map.end(); ++it )
{
int key = it->first;
string value = it->second;
}
}
要素を変更する必要がある場合:
const_iterator
ではなくiterator
を使用します。イテレータから値をコピーする代わりに、参照を取得し、それを通して値を変更します。
for(MyMap :: iterator it = my_map.begin(); it!= my_map.end(); ++ it){int key = it-> first; string&value = it-> second; if(value == "foo")value = "bar"; }
これは、通常、標準ライブラリコンテナを手動でトラバースする方法です。大きな違いは、map
の場合、*it
のタイプは要素自体ではなくpair
であるということです。
C++ 11コンパイラ(たとえば、--std=c++11
またはMSVCを使用した最新のGCC)の利点がある場合は、他のオプションもあります。
最初に、auto
キーワードを使用して、厄介な冗長性をすべて取り除くことができます。
#include <cstdlib>
#include <map>
#include <string>
using namespace std;
int main()
{
map<int,string> my_map;
// ... magic
for( auto it = my_map.begin(); it != my_map.end(); ++it )
{
int key = it->first;
string& value = it->second;
}
}
第二に、ラムダを使用することもできます。 decltype
と組み合わせて、これによりコードはよりクリーンになります(ただし、トレードオフはあります)
#include <cstdlib>
#include <map>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
map<int,string> my_map;
// ... magic
for_each(my_map.begin(), my_map.end(), [](decltype(*my_map.begin()) val)
{
string& value = val.second;
int key = val.first;
});
}
C++ 11は、範囲ベースfor
ループの概念も導入しています。これは、他の言語と同様に認識できます。ただし、一部のコンパイラはまだこれを完全にサポートしていません。特にMSVCです。
#include <cstdlib>
#include <map>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
map<int,string> my_map;
// ... magic
for(auto val : my_map )
{
string& value = val.second;
int key = val.first;
}
}
他のSTLコンテナと同様に、begin()
およびend()
メソッドは、マップの反復に使用できる反復子を返します。マップイテレータを間接参照すると、std::pair<const Key, Value>
。
STL map は、他のSTLコンテナと同じ方法でトラバースできます:イテレータを使用します。
for (std::map<key, value>::const_iterator
i = myMap.begin(), end = myMap.end(); i != end; ++i)
{
// *i is a key-value pair
}
C++ 17 であるため、 範囲ベースのforループ を 構造化バインディング とともに使用して、マップを反復処理できます。結果のコード、例えばマップのすべての要素を印刷するには、短くて読みやすいです:
std::map<int, std::string> m{ {3, "a"}, {5, "b"}, {9, "c"} };
for (const auto &[k, v] : m)
std::cout << "m[" << k << "] = " << v << std::endl;
出力:
m [3] = a
m [5] = b
m [9] = c
C++ 11以降の使用でfor
とともにauto
を使用する
map<int,int> map_variable; //you can use any data type for keys, as well as value
for(auto &x:map_variable)
{
cout<<x.first ;// gives the key
cout<<x.second; //gives the value
}
for
を使用するauto
の新しい形式は、C++ 11で導入されました。
Pythonのようないくつかの高レベル言語のような機能を提供するには
そのようなタイプの反復の実装がすでにあった場合
追伸:マップ変数は値のソートを保持するため、反復するとキーがソート順に取得されます
自動反復子を使用してマップを反復できます。
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
map<string, int> mp;
mp["a"]=500;
mp["b"]=200;
mp["d"]=300;
mp["c"]=400;
for(auto it=mp.begin(); it != mp.end(); it++)
{
cout<<it->first <<" : "<<it->second<<endl;
}
return 0;
}