How do i sort and transform a list of objects by different attributes.

Hello experts:

I am trying to sort a list of book objects by different attributes, e.g. last name, title, isbn, etc.  My first attempt was to sort by last name in the main program.  The compiler states that the function compare_last_name is an undeclared identifier.

 1.   I have a feeling the parameters in sort function (in the
main program) might be incorrect???
2.  I also want to use the transform function to change to lower case before I sort but am not sure how to do it for a specific data member, e.g. last name, title, etc.
   
Thank you
------------------------------------------------------------------
#include <string>
using namespace std;

# ifndef BOOK_H
# define BOOK_H

class Book
{
      public:
            Book() { };
            Book(string an_author_first_name, string an_author_last_name,
                   string a_title,string a_publisher, string an_isbn,
                   string a_pub_year, string a_page_count, string a_price,
                   string book_type);
//            ~Book();
            
            string get_author_first_name() const;
            string get_author_last_name() const;
            string get_title() const;
            string get_publisher() const;
            string get_isbn() const;
            string get_pub_year() const;
            string get_page_count() const;
            string get_price() const;
            string get_book_type()             
            int compare_last_name(Book&);
                        .
                                            .
                                            .
                                            .
            int add_book(string isbn, Book a_book);
            int delete_book(string isbn, Book a_book);
            void print_books();

      private:
            string author_first_name;
            string author_last_name;
            string title;
            string publisher;
            string isbn;
            string pub_year;
            string page_count;
            string price;
            string book_type;
};
#endif;





#include <iostream>
#include <sstream>
#include <iomanip>
#include "book8.h"

using namespace std;

string Book::get_author_first_name() const
{
      return author_first_name;
}
                .
                .
                .
                .

int Book::compare_last_name(Book& a_book)
{
      return author_last_name < a_book.author_last_name ||
               (author_last_name == a_book.author_last_name &&
               author_first_name < a_book.author_first_name) ||
               (author_last_name == a_book.author_last_name &&
               author_first_name == a_book.author_first_name &&
               title < a_book.title);
}


#include <list>
#include <string>
#include <fstream>
#include <iostream>
#include <algorithm>
#include "book8.h"

using namespace std;

void fill_list(list<Book>&, istream&);

template <class T>
inline void print_list(T& L, ostream& outfile, char* optional="")
{
      typename T::iterator pos;

      outfile << optional << endl;
      cout << optional << endl << endl;
      
      for (pos = L.begin(); pos != L.end(); ++pos)
      {
            outfile << *pos << ' ';
      }
      outfile << endl;
}

int main()
{
      list<Book> book_list;
      ifstream fin;
      ofstream fout;

      fin.open("C:\\CSC311\\Files\\book8_in.txt");
            
      if(fin.fail())
      {
            cout << "Failed to open input file" << endl;
            exit(1);
      }

      fout.open("C:\\CSC311\\Files\\book8_out.txt");

      if(fout.fail())
      {
            cout << "Failed to open output file"  << endl;
            exit(1);
      }

      fill_list(book_list, fin);
      print_list(book_list, fout, "Book List:\n");
              //transform();//?????????????????
    sort(book_list.begin(), book_list.end(), compare_last_name);
      print_list(book_list, fout, "Sorted Book List by Last Name:\n");
      
      fin.close();
      fout.close();      
      return 0;
}

void fill_list(list<Book>& book_list, istream& infile)
{
      Book a_book;

      while (!infile.eof())
      {
            infile >> a_book;
            book_list.push_back(a_book);
      }
}
deekakesAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

brettmjohnsonCommented:
You forgot the semicolon after the public: declaration of get_book_type()

         string get_book_type() ;

deekakesAuthor Commented:
The semicolon didn't quite make it when I copied and pasted the code.
efnCommented:
> 1.   I have a feeling the parameters in sort function (in the
> main program) might be incorrect???

You're right, the third one is incorrect.  What the sort function wants to see there is binary predicate, a function that takes two parameters and returns a bool value, such as:

bool compare_last_name(const Book& lhs, const Book& rhs);

You could make this function a static Book member function, or make it a free function.  If it's a free function, you will have to make it possible for the function to access the private Book member data you want to use in the comparison.  One way to do that is to declare the function as a friend of the Book class.

> 2.  I also want to use the transform function to change to lower case before I sort but am not sure how to do it for a specific data member, e.g. last name, title, etc.

The fourth argument to transform is a unary function.  In your case, the function would take a Book (or const Book&) as a parameter and return a (transformed) Book.  Within that function, you can do whatever you want, including access members of the argument Book.  Again, you will have to provide a way for the function to access the private members, just as with the function passed to sort.

--efn

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Learn SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

deekakesAuthor Commented:

I added the following to my program but am still having problems. (I made it a static member.) I'm pretty sure that one of the parameters should be a_book, but what should the other parameter be?

bool compare_last_name(const Book& a_book, const Book& a_book)
{
      return author_last_name < a_book.author_last_name ||
               (author_last_name == a_book.author_last_name &&
               author_first_name < a_book.author_first_name) ||
               (author_last_name == a_book.author_last_name &&
               author_first_name == a_book.author_first_name &&
               title < a_book.title);
}
GaryFxCommented:
b_book.   Seriously, you need to pass two different Book objects, and as long as you've chosen that naming convention, you may as well stick with it.

By making it a static function, you have eliminated the "this" variable within the body of the method.  Thus you'll need to change the occurrences on the left hand side to include an explicit object reference, e.g.
     b_book.author_last_name < a_book.author_last_name ||
   .... // You can take it from here

Also, if you've really made it a static member, you need to put the class name into the definition, i.e. bool Book::compare_last_name (or is that just a typo, since you had that right the first time)?

Gary
deekakesAuthor Commented:
Thanks....I have spent days trying to figure out a (seemingly) simple thing.....I think I just got to the point where I couldn't think logically!!!  I increased the points: 50 goes to Garyfx and the original 80 goes to efn.

Again, thanks for the help.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.