2
class SomeType { int32_t variable; }

std::vector<SomeType> myVector(10);

// ... code to work with myVector

std::vector<int32_t> myOtherVector;
for(int i = 0; i < myVector.size(); i++)
{
    myOtherVector.push_back(myVector[i].variable);
}

Is there a better way to do this? I've seen how I can use a lambda to do complex initialization, but I can't figure out how to "map" (in C# terms) a Type's certain fields onto this new vector.

halivingston
  • 3,727
  • 4
  • 29
  • 42

2 Answers2

4

It won't be initializing, but you can use std::transform:

myOtherVector.resize(myVector.size());
std::transform(myVector.cbegin(), myVector.cend(), myOtherVector.begin(), 
               [](auto const& s){
    return s.variable;
});

or with back_inserter:

myOtherVector.reserve(myVector.size()); // optional
std::transform(myVector.cbegin(), myVector.cend(), std::back_inserter(myOtherVector),
               [](auto const& s){
    return s.variable;
});

You can initialize it with Boost's transform_iterator:

auto tr = [](auto const& s){
    return s.variable;
});

vector<int32_t> myOtherVector(
    boost::make_transform_iterator(myVector.begin(), tr),
    boost::make_transform_iterator(myVector.end(), tr)
);
krzaq
  • 16,240
  • 4
  • 46
  • 61
  • very nice, I was just reading about transform, so good use case. – halivingston Oct 12 '16 at 00:55
  • you also choose between reserve vs resize? What's up with that? – halivingston Oct 12 '16 at 00:55
  • That's proably another question :) `reserve` just changes `vector`'s `capacity`. That is, its `size` does not change, but you can `push_back` without fear of reallocation (and invalidation of pointers, iterators and references) as long as `size` < `capacity`. On the other hand, `resize` changes the `size` of the vector, zero-initializing the elements if necessary. That's why the first version required a `resize` - because it depended on the size being no less than 10, while for the second it's just an optimization – krzaq Oct 12 '16 at 00:58
  • http://stackoverflow.com/questions/7397768/choice-between-vectorresize-and-vectorreserve – Pixelchemist Oct 12 '16 at 00:58
  • Thanks. I just realized though that I have to create two such smaller vectors, so while I like this, I'll be iterating twice if I use it, so I'll be using the loop instead :( – halivingston Oct 12 '16 at 01:05
  • Wow, `make_transform_iterator` is _incredibly_ useful! – Alejandro Oct 12 '16 at 01:09
0

I little better (IMHO)

for ( auto const &  elem : myVector )
{
    myOtherVector.emplace_back(elem.variable);
}
max66
  • 65,235
  • 10
  • 71
  • 111