We are committed to provide service 24 X 7

Deals, Shopping, Training, Tools

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.

Advertisements

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.

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

Cart

Your Cart is Empty

Back To Shop