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
The return type of
getProblem()
will be a problem, no pun intended, if thevector
does not contain at least one matching item. It will be better to return an iterator.Change the input to
getProblem()
aconst&
so that the retured iterator is valid when the function returns.After that, you can use
getProblem()
to implementcheckProblem()
.jcheckProblem()
can also be changed to accept aconst&
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
Linking a Shared Library with Another Shared Lib in Linux
Variable Assignment in an "If" Condition
Serial Comm Using Writefile/Readfile
Behaviour of Malloc with Delete in C++
Unit Testing for C++ Code - Tools and Methodology
Static Variables in an Inlined Function
When Is an Object "Out of Scope"
How to Use Std::Async Without Waiting for the Future Limitation
Why C++ Copy Constructor Must Use Const Object
How to Recover View Space Position Given View Space Depth Value and Ndc Xy
Lifetime of a String Literal Returned by a Function
A Base Class Pointer Can Point to a Derived Class Object. Why Is the Vice-Versa Not True
C++ Exception:Throwing Std::String
How to Parse Date/Time from String