C # - how to sort a list of strings using the last character, ignoring special character if there is one at the end

Below is the logic I was trying to implement and able to sort it, but needs to figure out to ignore special characters in it.

My logic:

  • Reversed string in a list
  • Sorted ascending
  • Sorted lines flipped back again &
  • Finally, it is returned as a string, appended to the ~ separator.

        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);
    
          

The conclusion I received Bananas!~Grape$~Cherry2~Guava~Mango~Apples

The expected result should be Guava~Grape$~Mango~Bananas!~Apples~Cherry2

Can anyone suggest me an optimized solution for sorting a list by the last character while ignoring special characters? Here I have used 2 lists to expand the lines, can this be done in a more efficient way? Note: without using LINQ PLS.

+3


source to share


3 answers


With a bit of LINQ and Regex, this can be done 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: A 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);
    }
}

      

+2


source


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 characters (and not just at the beginning of a line), as suggested in the comment, simply use Where

instead 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);
}

      

Note Where

has logic for queries ( char.IsLetter(x)

) versus SkipWhile

( !char.IsLetter(x)

).

+1


source


Find the last character that is a letter and sort 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));

      

No reverse required.

-1


source







All Articles