Sorting a CArray

The following is one example of a comparison function for a CArray collection. The comparison function can be used in qsort for sorting the array and in bsearch for searching it. In this case, I just use a simple CArray of integers (not an array of pointers to integers). Notice that there are also member functions that call qsort and bsearch, so it is not necessary to figure out how to do that. If you need to use this for a CArray of pointers, though, then depending on your experience with C++, it  might require a bit of time to get this working for an array of pointers. Sometime in the future I will add a sample for that too.

See "HOWTO: Quick Sorting Using MFC CArray-Derived Classes" for a Microsoft Knowledge Base article with another example. That article is critical to this solution, since it uses CArray::GetData, which implies that it is safe to use that function in this manner. When I first saw CArray::GetData being used this way, I was concerned that the MFC code for CArray might not always use a contiguous block of memory for the array elements, but that was before I saw the KB article. Since the KB article uses CArray::GetData, we can assume that the array elements will always be contiguous. For sorting a CStringArray, see Q120961 - HOWTO: How to Sort a CStringArray in MFC.

class CSortSearchArray : public CArray <int, int> {
	static int Compare(const void *, const void *);
public:
	void Sort() {qsort(GetData>(), GetSize(), sizeof(int), Compare);};
	int * Search(int i)
		{return (int *)bsearch(&i, GetData(), GetSize(), sizeof(int), Compare);};
};

int CSortSearchArray::Compare(const void *arg1, const void *arg2) {
	int int1=*(int *)arg1;
	int int2=*(int *)arg2;
if (int1 < int2)
	return -1;
else
	if (int1 > int2)
		return +1;
return 0;
}

The following is a little variation I have been working on. I hope to finish this soon, but it is a sample showing how to sort a field in a class that CArray is used to make an array of. I hope that this is enough for now to show how to make a couple more functions that would sort and search on other fields.

class CPlayer {
public:
	CString m_FirstName, m_LastName;
	float m_Average;
};

class CPlayers : public CArray <CPlayer, CPlayer&> {
	static int Compare(const void *, const void *);
public:
	void SortAverage() {qsort(GetData(), GetSize(), sizeof(CPlayer), Compare);};
	CPlayer * Search(CPlayer &Player)
		{return (CPlayer *)bsearch(&Player, GetData(), GetSize(), sizeof(CPlayer), Compare);};
};

int CPlayers::Compare(const void *arg1, const void *arg2) {
	CPlayer Player1=*(CPlayer *)arg1;
	CPlayer Player2=*(CPlayer *)arg2;
if (Player1.m_Average < Player2.m_Average)
	return -1;
else
	if (Player1.m_Average > Player2.m_Average)
		return +1;
return 0;
}

The following is a sample use:

	CPlayer Player, SearchPlayer;
	CPlayers Players;
//
Player.m_FirstName = "First";
Player.m_LastName = "Last";
Player.m_Average = 99;
Players.Add(Player);
Player.m_FirstName = "Sam";
Player.m_LastName = "Hobbs";
Player.m_Average = 11;
Players.Add(Player);
Player.m_FirstName = "Lannie";
Player.m_LastName = "Richard";
Player.m_Average = 100;
Players.Add(Player);
//
Players.SortAverage();
//
SearchPlayer.m_FirstName = "";
SearchPlayer.m_LastName = "";
SearchPlayer.m_Average = 11;
Player = *Players.Search(SearchPlayer);

See my Visual C++ Programmer Stuff page for more C++ stuff.