In this article, we will look into making ASCII Sort on a Collection in C# using LINQ.
Introduction
We got a requirement where we need to sort a column which is defined as under
- 1st case sort the column values by numbers
- 2nd case sort the column values by upper case
- 3rd case sort the column values by lower case
In the first glance, the problem statement appears complicated as one might think that we need to sort by number first, then by upper case and then by lower case. But if we minutely observe the problem, it's only the ASCII sorting. In this article, we will look into how to make it happen.
Using the code
Let us first prepare the sample data
var lstString = new List<string>()
{
"14",
"12",
"27 Oct contri head",
"563395",
"565302",
"8th Dec -12th Dec",
"sample string 4",
"add contribution head",
"Navarathri",
"Nov 5 Head Sumeru travel",
"Product A",
"WCF Contribution",
"test WCF",
""
};
First we will sort the records based on the default comparer as under
lstString.Sort();
At this point of time, the list is sorted by default.The Sort method modifies the same List instance. The result after sorting is presented below

However, we need to have an ASCII sort to satisfy our need. The below is the program for that
lstString =
lstString
.Where(w => w.ToCharArray().Length > 0) //sort those records whose length > 0 e.g. "" will be ignored
.Select(s => new { OriginalString = s, GetAsciiofFirstChar = (int)s.ToCharArray().Take(1).Single() }) //find the ascii of first charecters
.OrderBy(o => o.GetAsciiofFirstChar) //sort the records by ASCII character
.Select(s => s.OriginalString) //Project the sorted original string
.Union(lstString.Where(s => s.ToCharArray().Length == 0)) //Add those records to the sorted result whose length = 0 e.g. include ""
.ToList(); //Convert the IEnumerable to List
Let us look into the below code piece
GetAsciiofFirstChar = (int)s.ToCharArray().Take(1).Single()
Here first we are converting the string to an array of characters by using ToCharArray() and from that we are picking up the first character by using Take(1).But Take() extension method returns an IEnumerable and we need a single character. Hence, we use the Single() extension method that returns only element of an element sequence. And finally type casting the character to int helps us to get the ASCII of the first character of the string.
The rest of the code is simple to understand and it is heavily documented. The final result is presented below

The complete code is as under
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var lstString = new List<string>()
{
"14",
"12",
"27 Oct contri head",
"563395",
"565302",
"8th Dec -12th Dec",
"sample string 4",
"add contribution head",
"Navarathri",
"Nov 5 Head Sumeru travel",
"Product A",
"WCF Contribution",
"test WCF",
""
};
lstString.Sort(); //default sort
lstString =
lstString
.Where(w => w.ToCharArray().Length > 0) //sort those records whose length > 0 e.g. "" will be ignored
.Select(s => new { OriginalString = s, GetAsciiofFirstChar = (int)s.ToCharArray().Take(1).Single() }) //find the ascii of first charecters
.OrderBy(o => o.GetAsciiofFirstChar) //sort the records by ASCII character
.Select(s => s.OriginalString) //Project the sorted original string
.Union(lstString.Where(s => s.ToCharArray().Length == 0)) //Add those records to the sorted result whose length = 0 e.g. include ""
.ToList(); //Convert the IEnumerable to List
}
}
}
We can also create an Extension method on the List<string> for performing the ASCII Sort as describe under
public static class ListExtensions
{
public static List<string> ASCIISort(this List<string> lstString)
{
lstString =
lstString
.Where(w => w.ToCharArray().Length > 0) //sort those records whose length > 0 e.g. "" will be ignored
.Select(s => new { OriginalString = s, GetAsciiofFirstChar = (int)s.ToCharArray().Take(1).Single() }) //find the ascii of first charecters
.OrderBy(o => o.GetAsciiofFirstChar) //sort the records by ASCII character
.Select(s => s.OriginalString) //Project the sorted original string
.Union(lstString.Where(s => s.ToCharArray().Length == 0)) //Add those records to the sorted result whose length = 0 e.g. include ""
.ToList();
return lstString;
}
}
And invoke as
var newList = lstString.ASCIISort();// Ascii Sort
Conclusion
Hope this will be helpful for others too as this kind of sorting scenario is not so uncommon. Thanks for reading.