Reputation: 33
Below is the logic that i tried to implement and able to sort it but need to figure out to ignore special characters in it
My Logic:
Finally returned as a string by joining with ~ delimiter.
List<String> inputLst= new List<String>() { "Bananas!", "Cherry2",
"Mango","Apples", "Grape$", "Guava" };
List<String> sortList = new List<String>();
List<String> outputList = new List<String>();
foreach (String str in inputLst)
{
sortList.Add(new String(str.ToCharArray().Reverse().ToArray()));
}
sortList.Sort();
foreach (String str in sortList)
{
outputList.Add(new String(str.ToCharArray().Reverse().ToArray()));
}
Return String.Join("~", outputList);
Output i got is Bananas!~Grape$~Cherry2~Guava~Mango~Apples
Expected output should be Guava~Grape$~Mango~Bananas!~Apples~Cherry2
Could anyone please suggest me optimized solution to sort a list by last character by ignoring special characters? Here i used 2 lists for string reversals, can it be done in more efficient way? Note: without using LINQ pls.
Upvotes: 3
Views: 3662
Reputation: 24606
With a bit of LINQ and Regex, this can be achieved relatively simply:
var inputList = new List<string>() { "Bananas!", "Cherry2", "Mango","Apples", "Grape$", "Guava" };
var outputList = inputList.OrderBy(s => new string(Regex.Replace(s, "[^a-zA-Z]", "")
.Reverse()
.ToArray()))
.ToList();
var output = String.Join("~", outputList);
EDIT: Non-LINQ approach:
var inputList = new List<string>() { "Bananas!", "Cherry2", "Mango", "Apples", "Grape$", "Guava" };
inputList.Sort(new ReverseStringComparer());
var output = String.Join("~", inputList);
ReverseStringComparer:
class ReverseStringComparer : IComparer<string>
{
public int Compare(string x, string y)
{
string a = new string(Regex.Replace(x, "[^a-zA-Z]", "").Reverse().ToArray());
string b = new string(Regex.Replace(y, "[^a-zA-Z]", "").Reverse().ToArray());
return a.CompareTo(b);
}
}
Upvotes: 2
Reputation: 4189
Solution without regex:
string foo()
{
List<String> inputLst= new List<String>() { "Bananas!", "Cherry2", "Mango","Apples", "Grape$", "Guava" };
inputLst.Sort((l, r) => new string(l.Reverse().SkipWhile( x => !char.IsLetter(x) ).ToArray()).CompareTo( new string(r.Reverse().SkipWhile(x => !char.IsLetter(x)).ToArray()) ) );
return String.Join("~", inputLst);
}
To skip all non letter chars (and not only at the beginning of string) as suggested in comment, just use Where
instead of SkipWhile
like this:
string bar()
{
List<String> inputLst= new List<String>() { "Bananas!", "Cherry2", "Mango","Apples", "Grape$", "Guava" };
inputLst.Sort((l, r) => new string(l.Reverse().Where( x => char.IsLetter(x) ).ToArray()).CompareTo( new string(r.Reverse().Where(x => char.IsLetter(x)).ToArray()) ) );
return String.Join("~", inputLst);
}
Notice Where
has invers logic (char.IsLetter(x)
) compare to SkipWhile
(!char.IsLetter(x)
).
Upvotes: 1
Reputation: 14231
Find the last symbol being the letter and sort by it.
var inputList = new List<string>() {
"Bananas!", "Cherry2", "Mango","Apples", "Grape$", "Guava" };
var outputList = inputList.OrderBy(s => s.Last(c => char.IsLetter(c)));
Console.WriteLine(string.Join("~", outputList));
Reverse is not needed.
Upvotes: -1