C++ : How to Sort a List of objects with custom Comparator or lambda function

In this example we will discuss different ways to sort a std::list of user defined data types with custom comparators or lambda functions.

Suppose we have a type Player that contains Id and name.

struct Player
{
	int id;
	std::string name;

	Player(int playerId, std::string playerName) :
			id(playerId), name(playerName)
	{
	}
	bool operator <(const Player & playerObj) const
	{
		return id < playerObj.id;
	}
};

It has its < operator overloaded, which compares 2 Player objects using < on its ID field.

Now lets create a list of Player objects i.e.

std::list<Player> listofPlayers = { Player(22, "Sid"),
									Player(3, "Laura"),
									Player(43, "Riti"),
									Player(30, "Angel"),
									Player(2, "Laura"),};

Now we want to sort this list of Players and we are going to use std::list::sort() for this.

std::list::sort

std::list::sort has two different overloaded versions i.e.

void std::list::sort();

It uses the default sorting criteria i.e. will use < opeartor to compare the elements in list while sorting.
template <class Compare>
void sort (Compare comparator);

It accepts a Compare function or function object and use this comparator to compare the elements in list while sorting.

Advertisements

Lets discuss each of them,

Sorting a List with Default Criteria

To sort a std::list with default criteria i.e < operator of type, We will use version of sort() function that accepts no arguments i.e.

// Sort List by default criteria i.e < operator of Player
listofPlayers.sort();

It will sort the list using < operator of struct Player. Thus all the players will be sorted by their ID i.e.
2 :: Laura
3 :: Laura
22 :: Sid
30 :: Angel
43 :: Riti

Now suppose we want to sort the list of Player objects using their name instead of ID. It cannot be done by using default < operator of Player in sort(). So, we will use other overloaded version of sort().

Sorting a List of Objects with Custom Comparator & Function Object

std::list::sort has an another overloaded version that accepts a function pointer as an argument and use that for comparison while sorting.

template <class Compare>
void sort (Compare comparator);

Define a comparator or function object that will compare two Player Objects using their name.
struct PlayerComparator
{
	// Compare 2 Player objects using name
	bool operator ()(const Player & player1, const Player & player2)
	{
		if(player1.name == player2.name)
			return player1 < player2;
		return player1.name < player2.name;

	}
};

Now use the above Function object to sort the list of Player objects using name i.e.
// Sorting List using Function Objects as comparator
listofPlayers.sort(PlayerComparator());

Output:
30 :: Angel
2 :: Laura
3 :: Laura
43 :: Riti
22 :: Sid

Sorting a List of Objects with Custom Comparator & Lambda Function

We can also sort a list of Player objects by name using a Lambda function instead of defining a seperate Function object like above.

We can pass a lambda function in sort() as argument. this lambda function will compare two Player objects by name.

// Sorting List using Lambda Function as comparator
listofPlayers.sort([](const Player & player1, const Player & player2)
		{
			if(player1.name == player2.name)
				return player1 < player2;
			return player1.name < player2.name;
		});

Now sort() will use passed lambda function to compare the Player objects while sorting.

Output:

30 :: Angel
2 :: Laura
3 :: Laura
43 :: Riti
22 :: Sid

Complete example is as follows,
#include <iostream>
#include <list>
#include <string>
#include <algorithm>

struct Player
{
	int id;
	std::string name;

	Player(int playerId, std::string playerName) :
			id(playerId), name(playerName)
	{
	}
	bool operator <(const Player & playerObj) const
	{
		return id < playerObj.id;
	}
};

struct PlayerComparator
{
	// Compare 2 Player objects using name
	bool operator ()(const Player & player1, const Player & player2)
	{
		if(player1.name == player2.name)
			return player1 < player2;
		return player1.name < player2.name;

	}
};
int main()
{
	std::list<Player> listofPlayers = { Player(22, "Sid"),
										Player(3, "Laura"),
										Player(43, "Riti"),
										Player(30, "Angel"),
										Player(2, "Laura"),};


	std::cout<<"****Playes in the list Initially ****"<<std::endl;

	for(Player & player : listofPlayers)
		std::cout<<player.id<< " :: "<<player.name<<std::endl;

	// Sort List by default criteria i.e < operator of Player
	listofPlayers.sort();

	std::cout<<"****After Sorting By ID ****"<<std::endl;
	for(Player & player : listofPlayers)
		std::cout<<player.id<< " :: "<<player.name<<std::endl;


	std::cout<<"****After Sorting By Name ****"<<std::endl;

	// Sorting List using Lambda function as comparator
	listofPlayers.sort([](const Player & player1, const Player & player2)
			{
				if(player1.name == player2.name)
					return player1 < player2;
				return player1.name < player2.name;
			});

	for(Player & player : listofPlayers)
		std::cout<<player.id<< " :: "<<player.name<<std::endl;

	std::cout<<"****After Sorting By Name ****"<<std::endl;

	// Sorting List using Function Objects as comparator
	listofPlayers.sort(PlayerComparator());

	for(Player & player : listofPlayers)
		std::cout<<player.id<< " :: "<<player.name<<std::endl;

	return 0;
}

 

Output:

****Playes in the list Initially ****
22 :: Sid
3 :: Laura
43 :: Riti
30 :: Angel
2 :: Laura
****After Sorting By ID ****
2 :: Laura
3 :: Laura
22 :: Sid
30 :: Angel
43 :: Riti
****After Sorting By Name ****
30 :: Angel
2 :: Laura
3 :: Laura
43 :: Riti
22 :: Sid
****After Sorting By Name ****
30 :: Angel
2 :: Laura
3 :: Laura
43 :: Riti
22 :: Sid

 

To compile the above code in linux use following command,

g++ –std=c++11 example.cpp

Do you want to Learn Modern C++ from best?

We have curated a list of Best C++ Courses, that will teach you the cutting edge Modern C++ from the absolute beginning to advanced level. It will also introduce to you the word of Smart Pointers, Move semantics, Rvalue, Lambda function, auto, Variadic template, range based for loops, Multi-threading and many other latest features of C++ i.e. from C++11 to C++20.

Check Detailed Reviews of Best Modern C++ Courses

Remember, C++ requires a lot of patience, persistence, and practice. So, start learning today.

Leave a Comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top