Sorting a vector of objects in C ++

Let's say I have a class "Information", and it saves the name and age of people in the vector.

So...

class Information { private: int age; string name; //etc, etc... }; 

How do I sort a vector in ascending / descending order by age?

I believe that you are using something like this.

 sort(listOfPeople.begin(), listOfPeople.end(), greater<Information>()); 

listOfPeople will be a vector.

Any help would be greatly appreciated.

+6
source share
5 answers

If you want to sort them in descending order of age, one way to do this is to define a functor for comparison:

 class CompareInformations { public: // after making CompareInformations a friend class to Information... operator(const Information& rhs, const Information& lhs) { return rhs.age < lhs.age; } }; 

And then make your choice:

 sort(listOfPeople.begin(), listOfPeople.end(), CompareInformations()); 

You can also overload operator< for your class and dispense with the comparison object:

 // inside your class bool operator <(const Information& rhs) { return age < rhs.age; } 

Then do the sorting:

 sort(listOfPeople.begin(), listOfPeople.end()); 

The above examples assume that you want to sort by non- destructive (almost ascending, but not quite) order. To execute a non-increasing order, simply change all occurrences < to > .

+6
source

You need to create a comparator function or functor class that accepts two Information links and returns true if the first should be ordered before the second.

The following will be sorted from oldest to youngest:

 bool CompareAges(const Information & left, const Information & right) { return left.age > right.age; } std::sort(listOfPeople.begin(), listOfPeople.end(), CompareAges); 

To choose whether to sort ascending or descending, you can have two different sort calls with different comparison functions, or you can create a functor class with a flag that determines how elements are sorted.

 struct CompareAgesUpOrDown { CompareAgesUpOrDown(bool bDown) : m_bDown(bDown) {} bool operator() (const Information & left, const Information & right) { if (m_bDown) return left.age < right.age; else return left.age > right.age; } bool m_bDown; }; bool bDown = ...; std::sort(std::sort(listOfPeople.begin(), listOfPeople.end(), CompareAgesUpOrDown(bDown)); 
+3
source

Others have already demonstrated solutions in C ++ 98/03. In C ++ 11, you can use lambda instead for comparison:

 // ascending age: std::sort(people.begin(), people.end(), [](person const &a, person const &b) { return a.age < b.age; }); // descending age: std::sort(people.begin(), people.end(), [](person const &a, person const &b) { return b.age < a.age; }); 

And in case this happens:

 // ascending name: std::sort(people.begin(), people.end(), [](person const &a, person const &b) { return a.name < b.name; }); // descending name: std::sort(people.begin(), people.end(), [](person const &a, person const &b) { return b.name < a.name; }); 

IMO, Information is too common a name, so I changed it to person . In contrast, listOfPeople places too much emphasis on form rather than content (and, even worse, this is simply wrong, since you really have a vector of people, not a list at all). IMO, in programming it is usually better to use list only to refer to a linked list, and not to linear data structures in general.

+2
source

To use this sorting, you need to have a comparison function or object. See the sorting page at cplusplus.com for examples and information.

Here is a complete example of using the comparison function:

 #include <iostream> #include <string> #include <vector> #include <algorithm> class Information { public: Information(int age, std::string name) : m_age(age), m_name(name) {} int age() const { return m_age; } std::string name() const { return m_name; } private: int m_age; std::string m_name; friend bool sortInformationByAgeAscending(const Information& lhs, const Information& rhs); friend bool sortInformationByAgeDescending(const Information& lhs, const Information& rhs); }; bool sortInformationByAgeAscending(const Information& lhs, const Information& rhs) { return lhs.m_age < rhs.m_age; } bool sortInformationByAgeDescending(const Information& lhs, const Information& rhs) { return lhs.m_age > rhs.m_age; } int main (int argc, const char * argv[]) { std::vector<Information> info; info.push_back(Information(1, "Bill")); info.push_back(Information(5, "Ann")); info.push_back(Information(2, "Sue")); std::sort(info.begin(), info.end(), sortInformationByAgeAscending); std::cout << info.at(0).age() << ": " << info.at(0).name() << std::endl; std::cout << info.at(1).age() << ": " << info.at(1).name() << std::endl; std::cout << info.at(2).age() << ": " << info.at(2).name() << std::endl; return 0; } 
+1
source

I would overload operator < and then sort with more. Larger essentially means that rhs <LHS. Then you sort with sort(listOfPeople.begin(), listOfPeople.end(), greater<Information>());

If you decide to add operator< , your class will play well with std::set and as a key in std::map in addition to sorting permission.

 class Information { private: int age; string name; friend bool operator< (Information const& lhs, Information const& rhs){ return lhs.age < rhs.age; } //etc, etc... }; 
0
source

Source: https://habr.com/ru/post/895296/


All Articles