Ascii Sort on a Collection in C#

Rajnilari2015
Posted by in C# category on for Beginner level | Points: 250 | Views : 1008 red flag
Rating: 5 out of 5  
 1 vote(s)

In this article, we will look into making ASCII Sort on a Collection in C# using LINQ.
Recommendation
Read Compare two objects and list down the changes using LINQ before this article.

Introduction

We got a requirement where we need to sort a column which is defined as under

  1. 1st case sort the column values by numbers
  2. 2nd case sort the column values by upper case
  3. 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.

Page copy protected against web site content infringement by Copyscape

About the Author

Rajnilari2015
Full Name: Niladri Biswas (RNA Team)
Member Level: Platinum
Member Status: Member,MVP
Member Since: 3/17/2015 2:41:06 AM
Country: India
-- Thanks & Regards, RNA Team


Login to vote for this post.

Comments or Responses

Login to post response

Comment using Facebook(Author doesn't get notification)