Solved

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

Posted on 2003-11-09
6
346 Views
Last Modified: 2010-04-01
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);
      }
}
0
Comment
Question by:deekakes
6 Comments
 
LVL 23

Expert Comment

by:brettmjohnson
ID: 9710799
You forgot the semicolon after the public: declaration of get_book_type()

         string get_book_type() ;

0
 

Author Comment

by:deekakes
ID: 9711013
The semicolon didn't quite make it when I copied and pasted the code.
0
 
LVL 15

Accepted Solution

by:
efn earned 80 total points
ID: 9711065
> 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
0
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 

Author Comment

by:deekakes
ID: 9711518

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);
}
0
 
LVL 6

Assisted Solution

by:GaryFx
GaryFx earned 50 total points
ID: 9711600
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
0
 

Author Comment

by:deekakes
ID: 9711654
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.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now