find_if with vector of data structures

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • barabenka
    New Member
    • Jun 2007
    • 5

    find_if with vector of data structures

    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.
  • ilikepython
    Recognized Expert Contributor
    • Feb 2007
    • 844

    #2
    Originally posted by barabenka
    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?

    Comment

    • barabenka
      New Member
      • Jun 2007
      • 5

      #3
      Originally posted by ilikepython
      What kind of comparisons do you want to make?
      I would like to find record based on given id, so Record.ID==Give nID.

      Comment

      • ilikepython
        Recognized Expert Contributor
        • Feb 2007
        • 844

        #4
        Originally posted by barabenka
        I would like to find record based on given id, so Record.ID==Give nID.
        Maybe it's better to write your own function:
        [code=cpp]
        vector<Record>: :iterator it;

        int givenID = 16825 //sample ID

        for (it = myRecords.begin (); it != myRecords.end() ; it++)
        {
        if (*it.ID == givenID)
        {
        break;
        }
        }
        // "it" is the pointer to the record in myrecods with id 16825
        [/code]
        But maybe someone else can give a solution using find_if if that's what you want.
        Last edited by ilikepython; Jun 14 '07, 11:44 PM. Reason: rephrased sentence

        Comment

        • barabenka
          New Member
          • Jun 2007
          • 5

          #5
          Originally posted by ilikepython
          Maybe it's better to write your own function:
          [code=cpp]
          vector<Record>: :iterator it;

          int givenID = 16825 //sample ID

          for (it = myRecords.begin (); it != myRecords.end() ; it++)
          {
          if (*it.ID == givenID)
          {
          break;
          }
          }
          // "it" is the pointer to the record in myrecods with id 16825
          [/code]
          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...

          Comment

          • ilikepython
            Recognized Expert Contributor
            • Feb 2007
            • 844

            #6
            Originally posted by barabenka
            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?

            Comment

            • barabenka
              New Member
              • Jun 2007
              • 5

              #7
              Originally posted by ilikepython
              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.

              Comment

              • weaknessforcats
                Recognized Expert Expert
                • Mar 2007
                • 9214

                #8
                Nobody said how to use find_if() with a vector.

                You use find-if() with vector::iterato r 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:
                [code=cpp]
                vector<Record> MyRecords;

                vector<Record>: :iterator start = MyRecords.begin ();
                vector<Record>: :iterator end = MyRecords.end() ;
                if (find_if(start, end, testfunc) != MyRecords.end() )
                {
                cout << "Found";
                }
                else
                {
                cout << "Not found";
                }
                //where:

                bool testfunc(const Record& arg)
                {
                if (arg.Data1 == 1234) return true;
                return false;
                }
                [/code]

                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.

                Comment

                • ilikepython
                  Recognized Expert Contributor
                  • Feb 2007
                  • 844

                  #9
                  Originally posted by weaknessforcats
                  Nobody said how to use find_if() with a vector.

                  You use find-if() with vector::iterato r 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:
                  [code=cpp]
                  vector<Record> MyRecords;

                  vector<Record>: :iterator start = MyRecords.begin ();
                  vector<Record>: :iterator end = MyRecords.end() ;
                  if (find_if(start, end, testfunc) != MyRecords.end() )
                  {
                  cout << "Found";
                  }
                  else
                  {
                  cout << "Not found";
                  }
                  //where:

                  bool testfunc(const Record& arg)
                  {
                  if (arg.Data1 == 1234) return true;
                  return false;
                  }
                  [/code]

                  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?

                  Comment

                  • weaknessforcats
                    Recognized Expert Expert
                    • Mar 2007
                    • 9214

                    #10
                    Originally posted by ilikepython
                    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:
                    [code=cpp]
                    class Search
                    {
                    int ID;
                    int Data1;
                    int Data2;
                    Record rcd;
                    };
                    [/code]

                    Then implement the function operator:

                    [code=cpp]
                    class Search
                    {
                    int ID;
                    int Data1;
                    int Data2;
                    Record rcd;
                    public:
                    bool operator(const Record& arg);
                    };

                    int main()
                    {
                    Search ss;
                    vector<Record> MyRecords;
                    find_if(MyRecor ds.begin(), MyRecords.end() , ss);
                    }
                    [/code]

                    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.

                    Comment

                    • ilikepython
                      Recognized Expert Contributor
                      • Feb 2007
                      • 844

                      #11
                      Originally posted by weaknessforcats
                      You create a class for what you want to search on:
                      [code=cpp]
                      class Search
                      {
                      int ID;
                      int Data1;
                      int Data2;
                      Record rcd;
                      };
                      [/code]

                      Then implement the function operator:

                      [code=cpp]
                      class Search
                      {
                      int ID;
                      int Data1;
                      int Data2;
                      Record rcd;
                      public:
                      bool operator(const Record& arg);
                      };

                      int main()
                      {
                      Search ss;
                      vector<Record> MyRecords;
                      find_if(MyRecor ds.begin(), MyRecords.end() , ss);
                      }
                      [/code]

                      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.

                      Comment

                      Working...