найти в std :: vector & lt; std :: pair & gt;

У меня есть вектор пар. Первый в паре имеет тип std :: string, а второй имеет тип Container.

Какая удобная функциональность существует в std или boost, чтобы я мог возвращать контейнер с заданным строковым значением в качестве ключа?

ОБНОВИТЬ

Было отмечено, что я мог бы вместо этого использовать std :: map, но на самом деле мне нужно сохранить порядок своих элементов в том порядке, в котором я помещаю их в вектор.

10

Решение

Возможное решение:

struct comp
{
comp(std::string const& s) : _s(s) { }

bool operator () (std::pair<std::string, Container> const& p)
{
return (p.first == _s);
}

std::string _s;
};

// ...

typedef std::vector<std::pair<std::string, Container> > my_vector;
my_vector v;

// ...

my_vector::iterator i = std::find_if(v.begin(), v.end(), comp("World"));
if (i != v.end())
{
Container& c = i->second;
}

// ...

Вот полный пример:

#include <vector>
#include <utility>
#include <string>
#include <algorithm>

struct Container
{
Container(int c) : _c(c) { }
int _c;
};

struct comp
{
comp(std::string const& s) : _s(s) { }

bool operator () (std::pair<std::string, Container> const& p)
{
return (p.first == _s);
}

std::string _s;
};

#include <iostream>

int main()
{
typedef std::vector<std::pair<std::string, Container> > my_vector;
my_vector v;
v.push_back(std::make_pair("Hello", Container(42)));
v.push_back(std::make_pair("World", Container(1729)));
my_vector::iterator i = std::find_if(v.begin(), v.end(), comp("World"));
if (i != v.end())
{
Container& c = i->second;
std::cout << c._c; // <== Prints 1729
}
}

И вот живой пример.

7

Другие решения

С помощью Boost.Range а также Boost.Bind, вы можете сделать это:

struct predicate
{
template<class Key, class Pair>
bool operator()(const Key& k, const Pair& p) const
{
return p.first == k;
}
};

// Your vector of pairs
std::vector<std::pair<std:string, Container> v = ...;
// The key you would like to search for
std::string key = ...;
Container& c = boost::find_if(v, boost::bind(predicate(), key, _1))->second;
1

Есть простое решение: использовать std::copy а также std::inserter:

#include <algorithm>
#include <map>
#include <string>
#include <utility> // pair
#include <vector>

void function()
{
typedef int Data;
typedef std::pair< std::string, Data > String_Data_Pair;
typedef std::vector< String_Data_Pair > String_Data_Pair_Sequence;
typedef std::map< std::string, Data > String_To_Data_Map;

String_Data_Pair_Sequence string_data_pairs;

/* fill 'string_data_pairs' here */

String_To_Data_Map string_to_data_map;

std::copy( string_data_pairs.begin(),
string_data_pairs.end(),
std::inserter( string_to_data_map,
string_to_data_map.begin() /* superfluous, but required */ ) );
}
0

class SomeClass{
int num;
public:
SomeClass();
void setNumber(int n) const { num = n;}
};

vector<pair<SomeClass,string> > vectr;

for(unsigned int i = 0; i < vectr.size(); i++)
if(vectr[i].second == "key")
vectr[i].first.setNumber(50);

Работал на меня!

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector