How to sort a Alphanumeric string with special characters in C# using Linq? Order should be first special characters, then numbers and then alphabets.
Example :
Input - { Hello, #Test, @Red, &While, 123@Test, @123Test, TSun, Dom, Left }
Expected - { @123Test, TSun, @Red, #Test, &While, 123@Test, Dom, Hello, Left }
CodePudding user response:
As the standard string comparison does exactly that, you can just use OrderBy
:
var input = new[] { "Hello", "#Test", "@Red", "&While", "123@Test", "@123Test", "TSun", "Dom", "Left" };
foreach (var s in input.OrderBy(x => x)) Console.WriteLine(s);
Gives:
@123Test
@Red
&While
#Test
TSun
123@Test
Dom
Hello
Left
Since the string comparison is culture-dependent, this might be different depending on your current culture. If you want it culture-independent, use e.g. OrderBy(x => x, StringComparer.InvariantCulture)
.
CodePudding user response:
You may use custom implementation of IComparer, then pass it to OrderBy
call. E.g.:
public class SpecialCharactersNumbersLettersComparer : IComparer<string>
{
private readonly IComparer<string> defaultComparer = StringComparer.InvariantCulture;
private static int OrderOfChar(char ch)
{
if(Char.IsLetter(ch))
return 2;
if(Char.IsDigit(ch))
return 1;
return 0;
}
public int Compare(string left, string right)
{
if(string.IsNullOrEmpty(left)
|| string.IsNullOrEmpty(right)) {
return defaultComparer.Compare(left, right);
}
var leftChar = left[0];
var rightChar = right[0];
var leftOrder = OrderOfChar(leftChar);
var rightOrder = OrderOfChar(rightChar);
if(leftOrder == rightOrder)
return defaultComparer.Compare(left, right);
if(leftOrder > rightOrder)
return 1;
return -1;
}
}
public static List<string> SortSpecialCharactersNumbersAlphabet(IEnumerable<string> input)
{
return input.OrderBy(_ => _, new SpecialCharactersNumbersLettersComparer())
.ToList();
}
Used as:
Console.WriteLine(string.Join(", ",
SortSpecialCharactersNumbersAlphabet(new [] {
"Hello", "#Test", "@Red", "&While", "123@Test", "@123Test", "TSun", "Dom", "Left"})));
produces output:
@123Test, @Red, &While, #Test, TSun, 123@Test, Dom, Hello, Left