Vectors, Structs and Std::Find

Vectors, structs and std::find

std::find_if:

it = std::find_if(bot.monsters.begin(), bot.monsters.end(), 
boost::bind(&monster::id, _1) == currentMonster);

Or write your own function object if you don't have boost. Would look like this

struct find_id : std::unary_function<monster, bool> {
DWORD id;
find_id(DWORD id):id(id) { }
bool operator()(monster const& m) const {
return m.id == id;
}
};

it = std::find_if(bot.monsters.begin(), bot.monsters.end(),
find_id(currentMonster));

Search for and replace a value in a vector of structs

To change the elements in the vector, you need to take a reference in the range-for loop:

for (auto &e : data)

Otherwise you are making a copy, which doesn't change the original elements.

The 4th parameter of replace_if needs to take an info object, not just the new_name value.

Instead of replace_if, the appropriate algorithm to use here would be for_each, which modifies the info objects as needed:

std::for_each(data.begin(), data.end(), 
[old_name, new_name](info &i) {
if (i.name == old_name)
i.name = new_name;
});

However, in this case, the range-for loop is probably less code, and easier to read and write.

Also, please avoid using namespace std;, it's bad practice.

Searching c++ std vector of structs for struct with matching string

A straight-forward-approach:

struct FindByName {
const std::string name;
FindByName(const std::string& name) : name(name) {}
bool operator()(const Joints& j) const {
return j.name == name;
}
};

std::vector<Joints>::iterator it = std::find_if(m_jointsVector.begin(),
m_jointsVector.end(),
FindByName("foo"));

if(it != m_jointsVector.end()) {
// ...
}

Alternatively you might want to look into something like Boost.Bind to reduce the amount of code.

find struct in vector

May be you did not specified type for it?

std::vector<subscription>::iterator it = 
find(subscriptions.begin(), subscriptions.end(), match);

How to search in vector of structure by a structure attribute?

You could do that simply by iterating through the vector and comparing for the attribute. I guess you are not looking for optimizing procedure for this.

for( auto iter = CLIENT.begin(); iter != CLIENT.end() ; iter++ )
{
if( iter->sm_index == 5 ) // compare attribute for your structure
std::cout << " Found" << std::endl;
}

Edited

Here is a faster approach with std::binary_search.

Client target("",0, 5, 0);

bool found = std::binary_search( CLIENT.begin(), CLIENT.end(), target, []( Client a, Client b ){ return a.client_id < b.client_id; } );

found ? std::cout << "Found" << std::endl : std::cout << "Not found" << std::endl;

From a vector of structs, get a vector that collects one of the fields for every struct

so writing a method for each fields is a bit daunting and inelegant

An immediate fix for that is to pass the field identifier as an argument too.

std::vector<double> collect(double Point::* f, std::vector<Point> const& v) {
std::vector<double> output;
for (auto const& elem : v) {
output.push_back(elem.*f);
}
return output;
}

To be called like this:

collect(&Point::X, v);

If the types aren't always double, then the above can easily be made a template over the member type:

template<typename T>
std::vector<T> collect(T Point::* f, std::vector<Point> const& v) {
std::vector<T> output;
for (auto const& elem : v) {
output.push_back(elem.*f);
}
return output;
}

And finally, the term you are looking for this sort of extraction is "projection". I.e, what one gets when projecting a function onto an axis, very roughly speaking. In our case, the function maps an index of the vector to a Point, and the projection is onto the x axis, as it were.

It can also be written on the fly with the C++ standard library, or with the ranges-v3 library. Projection is a very common operation with ranges of items, so many range-centric libraries will have the facilities to do it.

c++: std::vector of std::vector inside a struct

A default member initializer inside a class or struct must have an = token and/or {curly braces}.

std::vector<std::vector<int>> myVector{4};

[Note this would be trickier if the type were just std::vector<int>, since curly braces for a vector imply a sequence of elements. std::vector<int>{4} is a vector with size one whose one element is 4, not a vector of four zeroes. But here it's fine because {4} can't convert to std::initializer_list<std::vector<int>>, so that constructor overload isn't eligible, and the vector(size_type) constructor does win.]

The example program has undefined behavior because reserve does not change the size or create any elements. So s.myVector[0] is invalid since the vector is still empty. Remember, reserve is just a setup hint for the vector. Any valid program that uses reserve would still be valid if you removed all the reserve calls.

Using resize instead would do what you seem to mean: make the size of myVector equal to 4, by creating 4 empty element vectors. Then the push_back would add the number 1 to the first of those vectors, resulting in data {{1}, {}, {}, {}}.

int main(){
myStruct s;
s.myVector.resize(4);
s.myVector[0].push_back(1);
return 0;
}

Comparing a vector and a vector of struct for matching values - c++

In your if statement you are trying to compare an element of randomnums which is of type std::string to an element of resultvec which is of type past_result. In order to compare the actual winningnums value of the struct, change your if-statement to:

if(randomnums.at(i) == resultvec.at(i).winningnums)
{
//output result
}


Related Topics



Leave a reply



Submit