Var.. BeeS.
Var.. BeeS.

Reputation: 33

C# - How to sort a list of strings using last character by ignoring special character if any at the end

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:

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

Answers (3)

Abion47
Abion47

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

Logman
Logman

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

Alexander Petrov
Alexander Petrov

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

Related Questions