次の点を考慮してください。
struct A
{
int i;
double d;
std::string s;
};
std::list<A> list_A;
list_A のすべての要素をマップにコピーして、マップ内のすべてのペアが list_A の要素を値として、その文字列s
をキーとして構成するようにしたいと思います。リストをループして各要素をその文字列とともにマップのキーとして挿入するよりもエレガントな方法はありますか?
私は標準ライブラリのアルゴリズムとラムダが大好きですが、次のような単純なものはありません。
for (const A& value : list_A) {
map_A.insert(std::make_pair(value.s, value));
}
他のメソッドはこのコードと同等の処理を行っており、このループは読みやすく、同じくらい高速です。
これにより、次の使用方法がわかりますtransform
。
std::pair<std::string, A> pairify(const A& a) { return std::make_pair(a.s, a); }
std::transform(list.begin(), list.end(), std::inserter(map, map.end()), pairify);
を使用する理由inserter
は次のとおりです。
挿入インターレーターは、通常は要素を上書きするアルゴリズム (コピーなど) がコンテナー内の特定の位置に新しい要素を自動的に挿入できるように設計された特殊なタイプの出力反復子です。
前回は詳細なしで回答が早すぎて申し訳ありません。コンパイル可能なコードは次のとおりです。
struct A
{
int i;
double d;
std::string s;
};
std::list<A> list_A;
std::pair<std::string, A> convert(const A &x) {
return make_pair(x.s,x);
}
int main() {
std::map<std::string,A> out;
std::transform(list_A.begin(), list_A.end(), std::inserter(out,out.end()),convert);
}
C++11 を使用している場合は、キャプチャでラムダ関数を使用できます。
std::map<std::string, A> m;
std::list<A> l;
std::for_each(l.begin(), l.end(),
[&](const A& a) {
m.insert(std::make_pair(a.s, a));
});
私はそれをset
: に保存するかもしれません。このようにして、マップ (s 自体) にデータの重複はありません:
struct A
{
bool operator < (const A& r_) const { return (s < r_.s); }
int i;
double d;
std::string s;
};
std::list<A> list_A;
std::set<A> set_A;
for ( std::list<A>::const_iterator itr = list_A.begin(); itr != list_A.end(); ++itr ) {
if ( ! set_A.insert(*itr).second ) {
// Handle duplicated elements
}
}
私はループを維持するかもしれません: このようにして、重複した要素を正しく処理することができます.