Hello,

I'm quite new to the world of C++ programming I just started to like and learn the language a year back.

I have a problem which is related to sorting. Let's say I wanted to sort multiple array containers containing related elements.

For example:

Array1		Array2		 Array3
       Name		Age		 Scores         
       =====            ===		 =====  
       John		 23		   1                   
       Arthur		 20		  71
       Vergil		 15		  777
       Kenneth	         25		   7
       Jason		 19		   6

How do I sort the three arrays such that when I sort array 1, array 2 and 3 will get sorted as well based on array1 sorting.

Your suggestions and comments is gladly appreciated.

thanks,
tonka

Hey Tonka!

Wouldn't it make more sense to use a structure (struct) to store the name, age and score for each person and then use one array of structures instead of three separate arrays?
That way you only have to sort one array.

In fact if you use a std::vector instead of an array things become even easier. You can use the std::sort() function to sort the vector. All you need to do is create at least one comparison function for the std::sort function to use.

Take a look at this example which uses a struct, a std::vector and std::sort:

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<iterator>

// here's our data structure
struct data
{
	std::string name;
	unsigned int age;
	unsigned int score;
};

// Function definitions...

// These are the comparison functions we'll be using later with the 
// std::sort method...
bool sortVecByNameAscending(data &d1, data &d2);
bool sortVecByAgeAscending(data &d1, data &d2);
bool sortVecByScoreAscending(data &d1, data &d2);
bool sortVecByNameDescending(data &d1, data &d2);
bool sortVecByAgeDescending(data &d1, data &d2);
bool sortVecByScoreDescending(data &d1, data &d2);

// we'll use this to output our data.
// takes a string message and a vector of data objects
// as parameters. 
void outputData(const std::string &msg, const std::vector<data>& dat);


// Here's the main function...
int main()
{
	//Create a vector to store some data
	std::vector<data> userData;

	// I'm just gonna create an instance of the structure and manually 
	// add some of your posted data to the vector using push_back
	data dat;
	dat.name="John";
	dat.age=23;
	dat.score=1;
	userData.push_back(dat);

	dat.name="Arthur";
	dat.age=20;
	dat.score=71;
	userData.push_back(dat);

	dat.name="Virgil";
	dat.age=15;
	dat.score=777;
	userData.push_back(dat);

	// OK now we've got some data, lets see what we've got...
	outputData("Initial data:", userData);

	// now we'll sort the vector based on the name Ascending (A-Z)
	std::sort(userData.begin(), userData.end(), sortVecByNameAscending);
	outputData("After sorting by name ascending (A-Z):", userData);

	// now lets sort by name descending (Z-A)
	std::sort(userData.begin(), userData.end(), sortVecByNameDescending);
	outputData("After sorting by name descending (Z-A)", userData);

	// sort by age ascending (low to high)
	std::sort(userData.begin(), userData.end(), sortVecByAgeAscending);
	outputData("After sorting by age ascending (low-high):", userData);

	// sort by age descending (high to low)
	std::sort(userData.begin(), userData.end(), sortVecByAgeDescending);
	outputData("After sorting by age descending (high-low):", userData);

	// sort by score ascending (low to high)
	std::sort(userData.begin(), userData.end(), sortVecByScoreAscending);
	outputData("After sorting by score ascending (low-high):", userData);

	// sort by score descending (high to low)
	std::sort(userData.begin(), userData.end(), sortVecByScoreDescending);
	outputData("After sorting by score descending (high-low):", userData);
	
	std::string dummy;
	std::cout << "Press return to continue...";
	getline(std::cin, dummy);
}

// Output a message and the contents of a vector of data objects.
void outputData(const std::string &msg, const std::vector<data>& dat)
{
	// display the passed in message and some headers..
	std::cout << msg << std::endl;
	std::cout << "Name\t\tAge\tScore" << std::endl;
	std::cout << "====\t\t===\t=====" << std::endl;

	// display the contents of the vector
	for(std::vector<data>::const_iterator iter = dat.begin(); iter!=dat.end(); iter++)
		std::cout << (*iter).name << "\t\t" << (*iter).age << "\t" << (*iter).score << std::endl; 

	std::cout << std::endl;
}

// sort methods
// name ascending (A-Z)
bool sortVecByNameAscending(data &d1, data &d2)
{
	return d1.name < d2.name;
}

// name descending (Z-A)
bool sortVecByNameDescending(data &d1, data &d2)
{
	return d1.name > d2.name;
}

// age ascending (low-high)
bool sortVecByAgeAscending(data &d1, data &d2)
{
	return d1.age < d2.age;
}

// age descending (high-low)
bool sortVecByAgeDescending(data &d1, data &d2)
{
	return d1.age > d2.age;
}

// score ascending (low-high)
bool sortVecByScoreAscending(data &d1, data &d2)
{
	return d1.score < d2.score;
}

// score descending (high-low)
bool sortVecByScoreDescending(data &d1, data &d2)
{
	return d1.score > d2.score;
}

See the attached .png for the output of the program.

All we've done in the program is:
1. We've created a structure to hold each user record (data)
2. We've put a few records into a std::vector (userData)
3. We've sorted the vector several times using different comparison functions with the std::sort function.

We created 6 comparison functions enabling us to sort the array on any of the three parts of the structure (name, age or score) in both ascending (A-Z / low-high) and descending (Z-A / high-low) order.

Far simpler than attempting to sort three arrays!

Cheers for now,
Jas.

Hi JasonHippy,

Thanks a lot! the solution you have presented actually solves my problem. Kudos to your solution!

Tonka

Hey Tonka!

Wouldn't it make more sense to use a structure (struct) to store the name, age and score for each person and then use one array of structures instead of three separate arrays?
That way you only have to sort one array.

In fact if you use a std::vector instead of an array things become even easier. You can use the std::sort() function to sort the vector. All you need to do is create at least one comparison function for the std::sort function to use.

Take a look at this example which uses a struct, a std::vector and std::sort:

#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<iterator>

// here's our data structure
struct data
{
	std::string name;
	unsigned int age;
	unsigned int score;
};

// Function definitions...

// These are the comparison functions we'll be using later with the 
// std::sort method...
bool sortVecByNameAscending(data &d1, data &d2);
bool sortVecByAgeAscending(data &d1, data &d2);
bool sortVecByScoreAscending(data &d1, data &d2);
bool sortVecByNameDescending(data &d1, data &d2);
bool sortVecByAgeDescending(data &d1, data &d2);
bool sortVecByScoreDescending(data &d1, data &d2);

// we'll use this to output our data.
// takes a string message and a vector of data objects
// as parameters. 
void outputData(const std::string &msg, const std::vector<data>& dat);


// Here's the main function...
int main()
{
	//Create a vector to store some data
	std::vector<data> userData;

	// I'm just gonna create an instance of the structure and manually 
	// add some of your posted data to the vector using push_back
	data dat;
	dat.name="John";
	dat.age=23;
	dat.score=1;
	userData.push_back(dat);

	dat.name="Arthur";
	dat.age=20;
	dat.score=71;
	userData.push_back(dat);

	dat.name="Virgil";
	dat.age=15;
	dat.score=777;
	userData.push_back(dat);

	// OK now we've got some data, lets see what we've got...
	outputData("Initial data:", userData);

	// now we'll sort the vector based on the name Ascending (A-Z)
	std::sort(userData.begin(), userData.end(), sortVecByNameAscending);
	outputData("After sorting by name ascending (A-Z):", userData);

	// now lets sort by name descending (Z-A)
	std::sort(userData.begin(), userData.end(), sortVecByNameDescending);
	outputData("After sorting by name descending (Z-A)", userData);

	// sort by age ascending (low to high)
	std::sort(userData.begin(), userData.end(), sortVecByAgeAscending);
	outputData("After sorting by age ascending (low-high):", userData);

	// sort by age descending (high to low)
	std::sort(userData.begin(), userData.end(), sortVecByAgeDescending);
	outputData("After sorting by age descending (high-low):", userData);

	// sort by score ascending (low to high)
	std::sort(userData.begin(), userData.end(), sortVecByScoreAscending);
	outputData("After sorting by score ascending (low-high):", userData);

	// sort by score descending (high to low)
	std::sort(userData.begin(), userData.end(), sortVecByScoreDescending);
	outputData("After sorting by score descending (high-low):", userData);
	
	std::string dummy;
	std::cout << "Press return to continue...";
	getline(std::cin, dummy);
}

// Output a message and the contents of a vector of data objects.
void outputData(const std::string &msg, const std::vector<data>& dat)
{
	// display the passed in message and some headers..
	std::cout << msg << std::endl;
	std::cout << "Name\t\tAge\tScore" << std::endl;
	std::cout << "====\t\t===\t=====" << std::endl;

	// display the contents of the vector
	for(std::vector<data>::const_iterator iter = dat.begin(); iter!=dat.end(); iter++)
		std::cout << (*iter).name << "\t\t" << (*iter).age << "\t" << (*iter).score << std::endl; 

	std::cout << std::endl;
}

// sort methods
// name ascending (A-Z)
bool sortVecByNameAscending(data &d1, data &d2)
{
	return d1.name < d2.name;
}

// name descending (Z-A)
bool sortVecByNameDescending(data &d1, data &d2)
{
	return d1.name > d2.name;
}

// age ascending (low-high)
bool sortVecByAgeAscending(data &d1, data &d2)
{
	return d1.age < d2.age;
}

// age descending (high-low)
bool sortVecByAgeDescending(data &d1, data &d2)
{
	return d1.age > d2.age;
}

// score ascending (low-high)
bool sortVecByScoreAscending(data &d1, data &d2)
{
	return d1.score < d2.score;
}

// score descending (high-low)
bool sortVecByScoreDescending(data &d1, data &d2)
{
	return d1.score > d2.score;
}

See the attached .png for the output of the program.

All we've done in the program is:
1. We've created a structure to hold each user record (data)
2. We've put a few records into a std::vector (userData)
3. We've sorted the vector several times using different comparison functions with the std::sort function.

We created 6 comparison functions enabling us to sort the array on any of the three parts of the structure (name, age or score) in both ascending (A-Z / low-high) and descending (Z-A / high-low) order.

Far simpler than attempting to sort three arrays!

Cheers for now,
Jas.