applying the std::find function to a vector of structures vector<myStruct) vec

This is a discussion on applying the std::find function to a vector of structures vector<myStruct) vec within the C++ Programming forums, part of the General Programming Boards category; I have asked a related question before, and it was resolved successfully. In the past, when I wanted to use ...

  1. #1
    Registered User
    Join Date
    May 2013
    Location
    United States
    Posts
    67

    applying the std::find function to a vector of structures vector<myStruct) vec

    I have asked a related question before, and it was resolved successfully. In the past, when I wanted to use std::max_element in order to find the maximum element (or even sort by using std::sort) of a vector of structures according to one of the members of the structure, all I had to do was to insert a specially designed comparison function as the third argument of the function std::max::element. But the latter comparison function naturally accepts two arguments internally.

    For instance, here is a test program that successfully finds the maximum according to just one member of the structure:

    Code:
    #include <iostream>
    #include <string>
    #include <vector>
    #include <algorithm>
    
    
    using namespace std;
    struct S {
      string myWord;
      int a;
      int b;
    };
    
    
    
    int main()
    { 
       vector<S> vec;
    
    
       for(int j=0; j<10; j++) { //Initialize:
             S tempS;
         tempS.a = j;
         tempS.b = 5+j;
         tempS.myWord = "aWord";
         vec.push_back(tempS);
       }
        
      
       std::vector<S>::iterator result;
         result = std::max_element(vec.begin(), vec.end(), [](const S & S_0, const S & S_1)  { return ( S_0.a < S_1.a ) ; } ) ;
       
    
       cout << "Maximum element S.a of vector<S> vec is at: " << std::distance(vec.begin(), result) << endl;
       cout << "---------------------------------------------" << endl;
    
    
       size_t range = 3 ;
       size_t index_max;
       
       for(vector<S>::iterator itr=vec.begin( ) + 6  ;  itr != vec.end( )  ;  itr++)
       {  
          size_t index = itr - vec.begin();
          vector<S>::iterator first = itr -range;
          //std::max_element(first, last) returns an answer between [first,last) as half-open interval
          //and so we need to further increase last=itr+1 as follows 
          // (or else the last element does not get compared):
          vector<S>::iterator last = itr +  1 ;
         // result = std::max_element( first , last, CompForMax_a  );
          result = std::max_element( first , last,  [](const S & S_0, const S & S_1)  { return ( S_0.a < S_1.a ) ; }   );
          index_max = std::distance(vec.begin(), result);
          cout << "max element of vec[i].a between slot " << index -range  << " and slot "
             << index << " is: " <<  (*result).a << ", and its index is: " <<  index_max << endl;
          cout << "vec[" << index << "].a = " << (*itr).a << endl;
          
       }
    
    }
    And the output was this, as expected:

    Maximum element S.a of vector<S> vec is at: 9
    ---------------------------------------------
    [I]max element of vec.a between slot 3 and slot 6 is: 6, and its index is: 6
    vec[6].a = 6
    [I]max element of vec.a between slot 4 and slot 7 is: 7, and its index is: 7
    vec[7].a = 7
    [I]max element of vec.a between slot 5 and slot 8 is: 8, and its index is: 8
    vec[8].a = 8
    [I]max element of vec.a between slot 6 and slot 9 is: 9, and its index is: 9
    vec[9].a = 9




    -------------------------------------------------------

    However, I now need to search and find an element of vector<myStruct> according to just one member of myStruct, instead of finding the maximum or sorting as before. This presents a problem because the function std::find does not accept such a comparison function as its third argument.

    This was the description of the std::find function that I found:
    find - C++ Reference
    Code:
     
    
    template <class InputIterator, class T>   InputIterator find (InputIterator first, InputIterator last, const T& val);
    
    
    I could also find another function called std::find_if, but this only accepts a unary predicate like this:
    find_if - C++ Reference
    Code:
     
    
    template <class InputIterator, class UnaryPredicate>   InputIterator find_if (InputIterator first, InputIterator last, UnaryPredicate pred);
    And once again this is either inadequate of I don't see how to use it directly, because for the third argument I would like to insert a function that takes two arguments with a syntax like this:
    Code:
    int x=7;
    
    std::vector<S>::iterator result;
       result = std::find(vec.begin(), vec.end(), []( const (int x, const S & S_1)  { return (  x == S_1.a ) ; } ) ;

    Is there another std function that I can use to make search and find an element according to just one member of myStruct?

    Or perhaps there is a clever way to pass two arguments to the unary predicate.
    Many thanks.




    Last edited by FortranLevelC++; 07-05-2013 at 03:01 AM.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,264
    std::find_if is appropriate here. One solution is to create a function object with the value that you want to compare against as a member variable. Another option, more in line with what you already have, is to make use of the x variable by bringing it into the scope of the lambda function, e.g.,
    Code:
    std::vector<S>::iterator result = std::find_if(
        vec.begin(),
        vec.end(),
        [x](const S& s) { return s.a == x; }
    );
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    May 2013
    Location
    United States
    Posts
    67
    Quote Originally Posted by laserlight View Post
    std::find_if is appropriate here. One solution is to create a function object with the value that you want to compare against as a member variable. Another option, more in line with what you already have, is to make use of the x variable by bringing it into the scope of the lambda function, e.g.,
    Code:
    std::vector<S>::iterator result = std::find_if(
        vec.begin(),
        vec.end(),
        [x](const S& s) { return s.a == x; }
    );

    This is the perfect solution, and I can see that I will be using this syntax for many years in the future! The trouble is that I don't yet understand the lambda functions. I need to do more homework from C++ books.

    Many thanks LaserLight: you have answered my question with the speed of light.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,264
    You're welcome. I notice that this site has a guide to Lambda Functions in C++11 which may be more accurate than the description that I have used.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    May 2013
    Location
    United States
    Posts
    67
    Quote Originally Posted by laserlight View Post
    You're welcome. I notice that this site has a guide to Lambda Functions in C++11 which may be more accurate than the description that I have used.

    Yes, I have been looking at Alex Allain's tutorial for several weeks, but the subject matter is difficult to internalize and understand without doing some homework, which is what I need.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 16
    Last Post: 06-13-2013, 07:15 PM
  2. How to find Index positions with a vector STL?
    By codeguy in forum C++ Programming
    Replies: 6
    Last Post: 01-11-2008, 01:07 PM
  3. How to find index of a particular record in a vector?
    By ketu1 in forum C++ Programming
    Replies: 7
    Last Post: 01-02-2008, 12:22 PM
  4. Vector of Structures
    By loopshot in forum C++ Programming
    Replies: 3
    Last Post: 10-23-2005, 10:19 PM
  5. Vector of structures
    By Highland Laddie in forum C++ Programming
    Replies: 6
    Last Post: 09-13-2005, 10:22 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21