Sort a vector of custom objects in C++
This post will discuss how to sort a vector of custom objects in C++.
The STL library provides the std::sort algorithm defined in the <algorithm> header, which can be used to sort objects of any type. There are many ways to do it:
1. Overload T::operator<(T) function
The recommended approach is to overload the operator< for the object class. This works as operator< is the default order used by the std::sort function (std::sort it calls std::less<> which will delegate the call to the operator<).
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
#include <iostream> #include <utility> #include <vector> #include <algorithm> struct Node { std::string first_name; std::string last_name; // constructor Node(std::string x, std::string y): first_name(x), last_name(y) {} // overload the operator< bool operator<(const Node &r) const { if (first_name != r.first_name) { return first_name < r.first_name; } return last_name < r.last_name; } // overload the operator> (if required) bool operator>(const Node &r) const { if (first_name != r.first_name) { return first_name > r.first_name; } return last_name > r.last_name; } }; int main() { std::vector<Node> v = { {"Barack", "Obama"}, {"George", "Washington"}, {"George", "Bush"}, {"Abraham", "Lincoln"}, {"John", "Tyler"}, {"John", "Kennedy"} }; // sorts vector in increasing order of their first names std::sort(v.begin(), v.end()); // sorts vector in decreasing order of their first names // std::sort(v.begin(), v.end(), std::greater<Node>()); for (const Node &node: v) { std::cout << '{' << node.first_name << ',' << node.last_name << '}'; std::cout << std::endl; } return 0; } |
Output:
{Abraham,Lincoln}
{Barack,Obama}
{George,Bush}
{George,Washington}
{John,Kennedy}
{John,Tyler}
2. Overload operator<(T, T) function
Instead of defining operator< (or operator>) as member functions of the class, we can also use them as free operators, as shown below:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
#include <iostream> #include <utility> #include <vector> #include <algorithm> struct Node { std::string first_name; std::string last_name; // constructor Node(std::string x, std::string y): first_name(x), last_name(y) {} }; // overload the operator< bool operator<(const Node &x, const Node &y) { if (x.first_name != y.first_name) { return x.first_name < y.first_name; } return x.last_name < y.last_name; } int main() { std::vector<Node> v = { {"Barack", "Obama"}, {"George", "Washington"}, {"George", "Bush"}, {"Abraham", "Lincoln"}, {"John", "Tyler"}, {"John", "Kennedy"} }; std::sort(v.begin(), v.end()); for (const Node &node: v) { std::cout << '{' << node.first_name << ',' << node.last_name << '}'; std::cout << std::endl; } return 0; } |
Output:
{Abraham,Lincoln}
{Barack,Obama}
{George,Bush}
{George,Washington}
{John,Kennedy}
{John,Tyler}
3. Custom Comparator
We can also write your own comparator and pass it to the std::sort function. The comparator function decides how to order an object with respect to another object during sorting. There are many ways to write and pass the comparator function:
1. C++11 – Pass Lambda as comparison parameter to sort()
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
#include <iostream> #include <utility> #include <vector> #include <algorithm> struct Node { std::string first_name; std::string last_name; // constructor Node(std::string x, std::string y): first_name(x), last_name(y) {} }; int main() { std::vector<Node> v = { {"Barack", "Obama"}, {"George", "Washington"}, {"George", "Bush"}, {"Abraham", "Lincoln"}, {"John", "Tyler"}, {"John", "Kennedy"} }; std::sort(v.begin(), v.end(), [](const Node &x, const Node &y) { // compare last names first if (x.last_name != y.last_name) { return x.last_name < y.last_name; } // compare first names only if the last names are equal return x.first_name < y.first_name; }); for (const Node &node: v) { std::cout << '{' << node.first_name << ',' << node.last_name << '}'; std::cout << std::endl; } return 0; } |
Output:
{George,Bush}
{John,Kennedy}
{Abraham,Lincoln}
{Barack,Obama}
{John,Tyler}
{George,Washington}
2. Overload bool operator()(T, T) for a custom type
Here, the idea is to pass an object of a class implementing the () operator to sort() as a comparison function.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
#include <iostream> #include <utility> #include <vector> #include <algorithm> struct Node { std::string first_name; std::string last_name; // constructor Node(std::string x, std::string y): first_name(x), last_name(y) {} }; struct comp { bool operator()(const Node &x, const Node &y) const { // compare last names first if (x.last_name != y.last_name) { return x.last_name < y.last_name; } // compare first names only if the last names are equal return x.first_name < y.first_name; } }; int main() { std::vector<Node> v = { {"Barack", "Obama"}, {"George", "Washington"}, {"George", "Bush"}, {"Abraham", "Lincoln"}, {"John", "Tyler"}, {"John", "Kennedy"} }; std::sort(v.begin(), v.end(), comp()); for (const Node &node: v) { std::cout << '{' << node.first_name << ',' << node.last_name << '}'; std::cout << std::endl; } return 0; } |
Output:
{George,Bush}
{John,Kennedy}
{Abraham,Lincoln}
{Barack,Obama}
{John,Tyler}
{George,Washington}
3. Using binary function
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
#include <iostream> #include <utility> #include <vector> #include <algorithm> struct Node { std::string first_name; std::string last_name; // constructor Node(std::string x, std::string y): first_name(x), last_name(y) {} }; bool fn(const Node &x, const Node &y) { // compare last names first if (x.last_name != y.last_name) { return x.last_name < y.last_name; } // compare first names only if the last names are equal return x.first_name < y.first_name; } int main() { std::vector<Node> v = { {"Barack", "Obama"}, {"George", "Washington"}, {"George", "Bush"}, {"Abraham", "Lincoln"}, {"John", "Tyler"}, {"John", "Kennedy"} }; std::sort(v.begin(), v.end(), fn); for (const Node &node: v) { std::cout << '{' << node.first_name << ',' << node.last_name << '}'; std::cout << std::endl; } return 0; } |
Output:
{George,Bush}
{John,Kennedy}
{Abraham,Lincoln}
{Barack,Obama}
{John,Tyler}
{George,Washington}
That's all about sorting a vector of custom objects in C++.
Thanks for reading.
To share your code in the comments, please use our online compiler that supports C, C++, Java, Python, JavaScript, C#, PHP, and many more popular programming languages.
Like us? Refer us to your friends and support our growth. Happy coding :)