Case-sensitive string comparison

I want to sort the lines case-sensitive: so if you start with capital “C” then it should be “bigger” (for example) than the one that starts with “c”, but also less than the one that starts with "d".

For example, a sorted list: "a", "A", "chi", "Che", "Chr"

It is written that string comparison methods are case sensitive by default. But it looks like my understanding of "case sensitive" is different from the standard.

None of the default methods that I tried ( String.CompareTo, String.Compare(with different values StringComparison)) gives the result I want.

Here is the code I used for testing:

using System;
using System.Collections.Generic;

public class Test
{
    public static void Main()
    {
        var list = new List<String> { "Che", "Chr", "chi", "a", "A" }; 

        // Any other way to sort goes here
        list.Sort((s1, s2) => s1.CompareTo(s2));

        for (var i = 0; i < list.Count; i++)
        {
            Console.WriteLine(list[i]);
        }
    }
}

: "a" "A" "Che" "chi" "Chr". , "c" "C" s.

, : , ( ) , ? - ?

+4
4

, - - : a < A < c < C= 97 < 65 < 99 < 67.

sealed class CustomComparer : Comparer<string>
{
    public override int Compare(string x, string y)
    {
        for (int i = 0; i < Math.Min(x.Length, y.Length); i++)
        {
            char xc = x[i];
            char yc = y[i];
            if (xc == yc)
                continue;
            char xcLow = char.ToLowerInvariant(xc);
            char ycLow = char.ToLowerInvariant(yc);
            if (xcLow == ycLow)
                return xc < yc ? 1 : -1;
            else
                return xcLow < ycLow ? -1 : 1;
        }
        return x.Length.CompareTo(y.Length);
    }
}

:

var list = new List<String> { "Che", "Chr", "chi", "a", "A" };
list.Sort(new CustomComparer()); // a, A, chi, Che, Chr
+6

, ( ), ( ). , - LINQ:

list.OrderBy (l => l.Substring(0,1)).ThenBy (l => l.ToLower())

: Che Chr

+1

This comparator seems to do what you are looking for.

class MyComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        var sets = x.ToCharArray().Zip(y.ToCharArray(), 
                  (LeftChar, RightChar) => new { LeftChar, RightChar });
        var charsToCompare = sets.FirstOrDefault(c => c.LeftChar != c.RightChar);
        if (charsToCompare == null)
            return 0;
        var lowers = char.ToLower(charsToCompare.LeftChar).CompareTo(char.ToLower(charsToCompare.RightChar));
        if (lowers == 0)
            return charsToCompare.RightChar.CompareTo(charsToCompare.LeftChar);
        else
            return char.ToUpper(charsToCompare.LeftChar).CompareTo(char.ToUpper(charsToCompare.RightChar));
    }
}

Tested with

public class Test
{
    public static void Main()
    {
        var list = new List<String> { "Che", "Chr", "chi", "a", "A" };

        // Any other way to sort goes here
        list.Sort(new MyComparer());
       // list.Sort((s1, s2) => s1.CompareTo(s2));

        for (var i = 0; i < list.Count; i++)
        {
            Console.WriteLine(list[i]);
        }
        Console.ReadKey();
    }
}



Output

a
A
chi
Che
Chr
0
source

You should use this string sorting method.

string.Compareinstead of a.CompareTo.

String.Compare("Foo", "foo", StringComparison.InvariantCulture)

will return true, giving you the sort order you want.

Applies to your example:

list.Sort((s1, s2) => string.Compare(s1, s2, StringComparison.InvariantCulture));
-1
source

Source: https://habr.com/ru/post/1544175/


All Articles