By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,986 Members | 1,960 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,986 IT Pros & Developers. It's quick & easy.

find_if with vector of data structures

P: 5
How can I use find_if with vector of data structures?

I have something like this:

struct Record{
int ID;
int Data1;
int Data2;
};

vector<Record> MyRecords;


I would like to find a record based on ID. Should I use find_if and how can I do it? I know how to use find_if with simple data types but do not know how to write function that checks the condition in this case.

Thank you a lot for your answer.
Jun 14 '07 #1
Share this Question
Share on Google+
10 Replies


ilikepython
Expert 100+
P: 844
How can I use find_if with vector of data structures?

I have something like this:

struct Record{
int ID;
int Data1;
int Data2;
};

vector<Record> MyRecords;


I would like to find a record based on ID. Should I use find_if and how can I do it? I know how to use find_if with simple data types but do not know how to write function that checks the condition in this case.

Thank you a lot for your answer.
What kind of comparisons do you want to make?
Jun 14 '07 #2

P: 5
What kind of comparisons do you want to make?
I would like to find record based on given id, so Record.ID==GivenID.
Jun 14 '07 #3

ilikepython
Expert 100+
P: 844
I would like to find record based on given id, so Record.ID==GivenID.
Maybe it's better to write your own function:
Expand|Select|Wrap|Line Numbers
  1. vector<Record>::iterator it;
  2.  
  3. int givenID = 16825      //sample ID
  4.  
  5. for (it = myRecords.begin(); it != myRecords.end(); it++)
  6. {
  7.     if (*it.ID == givenID)
  8.     {
  9.         break;
  10.     }
  11. }
  12. // "it" is the pointer to the record in myrecods with id 16825
  13.  
But maybe someone else can give a solution using find_if if that's what you want.
Jun 14 '07 #4

P: 5
Maybe it's better to write your own function:
Expand|Select|Wrap|Line Numbers
  1. vector<Record>::iterator it;
  2.  
  3. int givenID = 16825      //sample ID
  4.  
  5. for (it = myRecords.begin(); it != myRecords.end(); it++)
  6. {
  7.     if (*it.ID == givenID)
  8.     {
  9.         break;
  10.     }
  11. }
  12. // "it" is the pointer to the record in myrecods with id 16825
  13.  
But maybe someone else can give a solution using find_if if that's what you want.
Thank you a lot.

Interesting... it will require to scan the half of the vector (in average) to get the solution. Will find_if work faster than this?
I guess the fastest way would be to create map ID-> element number in the vector...
Jun 14 '07 #5

ilikepython
Expert 100+
P: 844
Thank you a lot.

Interesting... it will require to scan the half of the vector (in average) to get the solution. Will find_if work faster than this?
I guess the fastest way would be to create map ID-> element number in the vector...
According to this page find_if shouldn't be noticaebly faster than the one I wrote. If you need speed, then you could sort the vector based on the ID variable and do a binary search. That would definately be faster. Would that work?
Jun 15 '07 #6

P: 5
According to this page find_if shouldn't be noticaebly faster than the one I wrote. If you need speed, then you could sort the vector based on the ID variable and do a binary search. That would definately be faster. Would that work?

Yes it will work, thank you indeed.
Jun 15 '07 #7

weaknessforcats
Expert Mod 5K+
P: 9,197
Nobody said how to use find_if() with a vector.

You use find-if() with vector::iterator objects pointing at the search range and a predicate argument.

In STL speak, a predicate is a function with one argiment that returns a bool.

Here's your code:
Expand|Select|Wrap|Line Numbers
  1. vector<Record> MyRecords;
  2.  
  3. vector<Record>::iterator start = MyRecords.begin();
  4. vector<Record>::iterator end = MyRecords.end();
  5. if (find_if(start, end, testfunc) != MyRecords.end())
  6. {
  7.    cout << "Found";    
  8. }
  9. else
  10. {
  11.     cout << "Not found";
  12. }
  13. //where:
  14.  
  15. bool testfunc(const Record& arg)
  16. {
  17.       if (arg.Data1 == 1234) return true;
  18.       return false;
  19. }
  20.  
This example will locate the first element of the vector where the Data1 member of your struct is equal to 1234.

Lastly, it is doubtful if a home-grown method is faster since the STL templates are all optimized for speed.
Jun 15 '07 #8

ilikepython
Expert 100+
P: 844
Nobody said how to use find_if() with a vector.

You use find-if() with vector::iterator objects pointing at the search range and a predicate argument.

In STL speak, a predicate is a function with one argiment that returns a bool.

Here's your code:
Expand|Select|Wrap|Line Numbers
  1. vector<Record> MyRecords;
  2.  
  3. vector<Record>::iterator start = MyRecords.begin();
  4. vector<Record>::iterator end = MyRecords.end();
  5. if (find_if(start, end, testfunc) != MyRecords.end())
  6. {
  7.    cout << "Found";    
  8. }
  9. else
  10. {
  11.     cout << "Not found";
  12. }
  13. //where:
  14.  
  15. bool testfunc(const Record& arg)
  16. {
  17.       if (arg.Data1 == 1234) return true;
  18.       return false;
  19. }
  20.  
This example will locate the first element of the vector where the Data1 member of your struct is equal to 1234.

Lastly, it is doubtful if a home-grown method is faster since the STL templates are all optimized for speed.
Yea, I thought of that but I couldn't think of way to search the Id when you don't know it until runtime. The only thing I could think of was to use a global variable but that's not so good is it?
Jun 15 '07 #9

weaknessforcats
Expert Mod 5K+
P: 9,197
Yea, I thought of that but I couldn't think of way to search the Id when you don't know it until runtime. The only thing I could think of was to use a global variable but that's not so good is it?
You create a class for what you want to search on:
Expand|Select|Wrap|Line Numbers
  1. class Search
  2. {
  3.     int ID;
  4.     int Data1;
  5.     int Data2;
  6.     Record rcd;
  7. };
  8.  
Then implement the function operator:

Expand|Select|Wrap|Line Numbers
  1. class Search
  2. {
  3.     int ID;
  4.     int Data1;
  5.     int Data2;
  6.     Record rcd;
  7.     public:
  8.        bool  operator(const Record& arg);
  9. };
  10.  
  11. int main()
  12. {
  13.    Search ss;
  14.    vector<Record> MyRecords;
  15.    find_if(MyRecords.begin(), MyRecords.end(), ss);
  16. }
  17.  
You then write functions on the Search class that identify what is to be searched for. The Search objects are created at run time so the member cna be anything. The Record& argument will be an element of the vector since the operator() will be called by find_if for each element in the search range.

No global variables, please.
Jun 16 '07 #10

ilikepython
Expert 100+
P: 844
You create a class for what you want to search on:
Expand|Select|Wrap|Line Numbers
  1. class Search
  2. {
  3.     int ID;
  4.     int Data1;
  5.     int Data2;
  6.     Record rcd;
  7. };
  8.  
Then implement the function operator:

Expand|Select|Wrap|Line Numbers
  1. class Search
  2. {
  3.     int ID;
  4.     int Data1;
  5.     int Data2;
  6.     Record rcd;
  7.     public:
  8.        bool  operator(const Record& arg);
  9. };
  10.  
  11. int main()
  12. {
  13.    Search ss;
  14.    vector<Record> MyRecords;
  15.    find_if(MyRecords.begin(), MyRecords.end(), ss);
  16. }
  17.  
You then write functions on the Search class that identify what is to be searched for. The Search objects are created at run time so the member cna be anything. The Record& argument will be an element of the vector since the operator() will be called by find_if for each element in the search range.

No global variables, please.
Oh Ok, I get it, thanks.
Jun 17 '07 #11

Post your reply

Sign in to post your reply or Sign up for a free account.