Search for a Struct Item in a Vector by Member Data

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));

Searching a vector of structs for one data member, then printing all data members that match

First off your while loop condition is not wrong, but could be simplified by using operator bool instead:

while(inFS)
{
...
}

Second, your usage of std::find_if is incorrect. The third argument must be a callable of signature bool(Record) (possibly const or ref qualified) and returns an iterator to the first match.

From your variable names and strings I guess you want to search over the Records::recip members in your vector. std::find_if is a good way to achieve this:

auto comp = [&search](Record const& r) { return r.receip == search; };

for (auto it = std::find_if(input.begin(), input.end(), comp);
it != input.end();
it = std::find_if(++it, input.end(), comp))
{
// this loop iterates over all matches for search in Record::receip
Record& record = *it;
std::cout << record << '\n';
}

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;

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.

Search for a struct element in vector by id and return name

Based on the error message, it sounds like you have a C++/CLI project.

When a lambda is used inline like you have in the call to find_if(), it is really creating a small class for you that overrides operator (). Unfortunately the only way to call find_if() from a managed class is to do that yourself:

struct DeviceFinder
{
public:
DeviceFinder(const std::wstring& temp)
: m_temp(temp)
{
}

bool operator() (const deviceDescription_t& item) const
{
return item.deviceID == m_temp;
}

private:
const std::wstring& m_temp;
};

And then you would call find_if() like this:

auto iter = std::find_if(deviceList.begin(), deviceList.end(),
DeviceFinder(temp));

How to find out if a struct is present in a vector of structs by a variable within the struct

What you need is std::find_if():

auto it = std::find_if(vec.begin(), vec.end(), [](S s) { return 5 == s.id; } );
if (vec.end() != it)
do_this(); // it now points to the S instance found in the vector
else
do_that();

How to get an index number by struct id in vector

Use std::find_if to find the element. This returns an iterator to the element. And if you really want to know the index use std:distance:

int id_to_find = 1;

std:size_t found_idx = std::distance(
std::begin(people),
std::find_if(std::begin(people), std::end(people),
[=] (const person& p) { return p.p_id == id_to_find; })
);

But you should really use iterators in C++ unless you have a good reason to want indexes.

Function that returns struct item from a vector based on structs member data

  1. The return type of getProblem() will be a problem, no pun intended, if the vector does not contain at least one matching item. It will be better to return an iterator.

  2. Change the input to getProblem() a const& so that the retured iterator is valid when the function returns.

  3. After that, you can use getProblem() to implement checkProblem().j

  4. checkProblem() can also be changed to accept a const& although it is strictly not necessary.

std::vector<Problem>::const_iterator getProblem(int animalProblemNumber,
std::vector<Problem> const& problems)
{
return std::find_if(problems.begin(), problems.end(),
[animalProblemNumber](Problem const& item)
{ return item.treatment == animalProblemNumber; });
}

and

bool checkProblem(int animalProblemNumber, std::vector<Problem> const& problems)
{
return (getProblem(animalProblemNumber, problems) != problems.end());
}


Related Topics



Leave a reply



Submit