views:

132

answers:

3

How do I sort the below code by name, age and score... all three fields

 #include <string>
 #include <vector>
 #include <algorithm>

 struct student_t
 {
      std::string name;
      int age, score;
 };

 bool by_more_than_1_field( student_t const &lhs, student_t const &rhs )
 {
      // sort by name, age and score
 }

 int main()
 {
 std::vector< student_t > students;
 // populate students

 std::sort( students.begin(), students.end(), by_more_than_1_field );
 }
+4  A: 

I would write it like so:

bool by_more_than_1_field( student_t const &lhs, student_t const &rhs )
{
    return lhs.name < rhs.name ||
           lhs.name == rhs.name && lhs.age < rhs.age ||
           lhs.name == rhs.name && lhs.age == rhs.age && lhs.score < rhs.score;
}

This will allow you to sort the records prioritizing by name, age and score in that order. Changing the priorities around should be a simple exercise.

fbrereto
Our answers are equivalent. It's hard to tell which one is easier to read/maintain...
jslap
+2  A: 

You have to be carefull that your sorting criteria is transitive: if x ' y then y !< x. If it is not transitive, the sort operation result depends on the ordering of the array before the call, which you probably don't want.

bool by_more_than_1_field( student_t const &lhs, student_t const &rhs )
{
   if (lhs.name < rhs.name) 
      return true; 
   else if (rhs.name < lhs.name)
      return false;
   else // name equals.
      if (lhs. age  < rhs. age ) 
         return true; 
      else if (rhs. age  < lhs. age )
         return false;
      else // age and names equals
         return lhs.score < rhs.score;
}
jslap
+1  A: 
bool by_more_than_1_field( student_t const& lhs, student_t const& rhs )
{
    if( lhs.name < rhs.name )
        return true;
    else if( lhs.age < rhs.age )
        return true;
    else if( lhs.score < rhs.score )
        return true;

    return false;
}

Much easier to maintain than the others, and cleaner too!

tsalter
It will have some weird results. if rhs.name < lhs.name, it will check against the age.
jslap