# Thread: Can I use std::copy to take the projection of a vector<MyStruct> onto vector<T> ?

1. ## Can I use std::copy to take the projection of a vector<MyStruct> onto vector<T> ?

Hello, I have asked a similar question before, but this one is slightly different.

If I have a vector of structures vector<S>, it is possible to use std::sort in order to sort this vector according to only one of the elements of the struct S, and this is can be done by passing a comparison function as the third argument of std::sort.

For example, here is the code that sorts vector<S> by inserting a lambda function to control std::sort:

Code:
```
// sort algorithm example
#include <iostream>     // std::cout
#include <algorithm>    // std::sort
#include <vector>       // std::vector
#include  <string>

struct S {
int myInt;
float myFloat;
string myString;
};

int main () {

vector<S> vec;
vector<S> copyOfVec;
S tempS;

for(int k=0; k<10; k++){
tempS.myInt= k;
tempS.myFloat=(float)( sqrt(2.0)+k);
tempS.myString=to_string(k*20); // this std function converts numbers to string, but it is new, and exists only in C++0x
vec.push_back(tempS);
}

copyOfVec.resize(vec.size());

copy(vec.begin(), vec.end(), copyOfVec.begin() ); // copy vec onto copyOfVec starting at the beginning of copyOfVec
sort(copyOfVec.begin(), copyOfVec.end(), [](const S & S1, const S & S2){ return( S1.myInt > S2.myInt ) ; } ) ; // note the greater than sign ">" to make descending order

for(int k=0; k<vec.size(); k++){
cout<< " vec[k].myInt = " <<  vec[k].myInt << endl;
}

cout <<" ----------------- " << endl;

for(int k = 0; k<copyOfVec.size(); k++){
cout << " copyOfVec[k].myInt = " << copyOfVec[k].myInt << endl;
}

return 0;
}```
Now my question is this: Just as we could sort vector<S> by using std::sort as described above, is there a way to use std::copy to copy ONLY according to one of the "coordinates" of S (for example the element myInt of S in the program above) from the vector<S> onto another vector<int>? In other words, can we use some version of std::copy to take the projection of vector<S> onto vector<int> by copying vec.myInt elements onto vector<int> tempIntVec?

Many thanks.

2. There is std::copy_if for this purpose.

3. Originally Posted by laserlight
There is std::copy_if for this purpose.
Many thanks!

It seems that there are several options here.

But I am still confused because the unary predicate function is supposed to return a bool type, not an arbitrary type that is in the struct S.

This code is probably wrong, but this is what I had in mind. Is there a way to fix this?
Code:
```vector<int> vec_projection;
std::vector<int>::iterator result;
result = std::copy_if(vec.begin(), vec.end(), vec_projection.begin() ,
[](const S & s) ->int { return ( s.myInt ) ; } ) ;```

In this example, it seems that the iterator result ​ is not important because vec_projection "should" already have the necessary projected copy of S inside.

Normally the std::copy_if unary predicate should return a boolean condition, not an integer, and so what I wrote must be wrong, but how else can I copy a coordinate of vector<S> onto vector<int>?

4. Oh, I misread your question. What you want, rather, is std::transform, since you are transforming a range of S objects into a range of int objects.

5. Code:
```std::vector<int>::iterator result;
result = std::copy_if(vec.begin(), vec.end(), vec_projection.begin() ,
[](const S & s) ->int { return ( s.myInt ) ; } ) ;```
Simplification (though it still does not work):
Code:
```auto result =
std::copy_if(vec.begin(), vec.end(), vec_projection.begin(), [](const S & s)
{
return s.myInt;
});```
(You can deduce the return type. Furthermore, if your body of the lambda statement contains only a return statement, then you don't need to specify the return type.)

6. Originally Posted by laserlight
Oh, I misread your question. What you want, rather, is std::transform, since you are transforming a range of S objects into a range of int objects.
Many thanks! Finally the std::transform is working.

(But you did not misread my question: I am the one who made a mistake in the formulation of the question! When I originally wrote "is there a way to use std::copy to copy ONLY according to one of the "coordinates" of S ?" , this was misleading because it could have implied that I am really trying to copy by using a condition on the elements in S, not simply copying elements in S like vec_Projected[k] = vec[k].myInt. )