2013-06-12 2 views
2

Как скопировать все элементы вектора, который представляет собой структуру элементов, в набор ,Сохранение из std :: vector to std :: set где vector содержит структуру, но std :: set содержит только один элемент из структуры

struct info 
    { 
     std::string code; 
     std::string curDate; 
     int   iVar; 

    }; 

    std::vector<info> infVect; // Load data into the vector from the database 

    std::set<std::string> uniqueCodes; 


    for (int i = 0; i < infVect.size() ; ++i) 
     uniqueCodes.insert(infVect[i].code); 

Есть ли более быстрый способ хранения элементов из вектора для установки без повторения каждого элемента в цикле?

Примечание:

std::set<std::string> uniqueCodes(infVect.begin(), infVect.end()), будет работать, если infVect был только код. Но infVect - вектор объектов.

+5

Нет, нет более быстрого способа, чем посещение каждого элемента. Проверьте [std :: transform] (http://en.cppreference.com/w/cpp/algorithm/transform). – jrok

ответ

9

Ваш код абсолютно нормально. Цикл for - это самый простой способ выразить то, что вы имеете в виду в этой ситуации. C++ 11 диапазона на основе for еще проще:

for (const auto& i : infVect) 
    uniqueCodes.insert(i.code); 

Если вы хотите альтернативу ради наличия одного, вот как это сделать, только склейку функции STL.

Пропустите его через std::transform, чтобы извлечь элемент и вставить его в set. Помощник mem_fn превращает функцию-член или переменную-член в функтор.

std::transform(
    infVect.begin(), 
    infVect.end(), 
    std::inserter(uniqueCodes, uniqueCodes.end()), 
    std::mem_fn(&info::code) 
); 

Если code были частными, вам нужно геттер, чтобы дать mem_fn.

const std::string& getCode() const { return code; } 

Вам нужны следующие заголовки.

#include <algorithm> // transform 
#include <functional> // mem_fn 
#include <iterator> // inserter 

Если вы не заботитесь о сохранении оригинального vector, вы можете использовать std::move_iterator в C++ 11 для перемещения строк без перераспределения, и избежать <functional> зависимости для mem_fn с помощью лямбды.

using namespace std; // for brevity 
transform(
    make_move_iterator(begin(infVect)), 
    make_move_iterator(end(infVect)), 
    inserter(uniqueCodes, end(uniqueCodes)), 
    [](info&& x) { return move(x.code); } 
); 
+0

Спасибо, Джон. Ценить это. – user373215

1

Вы должны посетить каждый узел, но вы можете скрыть итерацию прочь в std::transform

struct StringFromInfo { std::string operator()(const Info& info) { return info.code; } }; 

std::transform(infVect.begin(), infVect.end(), std::back_inserter(uniqueCodes), StringFromInfo()); 
+0

'back_inserter' не будет работать на' set', потому что у него нет 'push_back'. Вам нужно «вставить». Мне жаль, что они не исправили это на C++ 11. –

+0

Спасибо, Джон. Ценить это. – user373215

Смежные вопросы