Oxyprogrammer
Oxyprogrammer

Reputation: 1263

string sorting in C#

I have an array of strings like the following:

"access"
"Addition"
"account"
"base"
"Brick"
"zammer"
"Zilon"

I want them to sort them witht the following rules"

  1. Capital letters for a given character should come first.
  2. The capital and small letters should be sorted in their own groups.

Thus, the output should be:

"Addition"
"access"
"account"
"Brick"
"base"
"Zilon"
"zammer"

The language I am using is C# and .Net 4.0.

Upvotes: 1

Views: 234

Answers (4)

Paulo Morgado
Paulo Morgado

Reputation: 14856

If you want to go beyond the first character, I should implement a comparer:

class MyComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        if ((x == null) && (y == null))
        {
            return 0;
        }

        if (x == null)
        {
            return 1;
        }

        if (y == null)
        {
            return -1;
        }

        var l = Math.Min(x.Length, y.Length);
        for (var i = 0; i < l; i++)
        {
            var c = x[i];
            var d = y[i];
            if (c != d)
            {
                if (char.ToLowerInvariant(c) == char.ToLowerInvariant(d))
                {
                    return StringComparer.Ordinal.Compare(new string(c, 1), new string(d, 1));
                }
                else
                {
                    return StringComparer.OrdinalIgnoreCase.Compare(new string(c, 1), new string(d, 1));
                }
            }
        }

        return x.Length == y.Length ? 0 : x.Length > y.Length ? 1 : -1;
    }
}

And then use it:

var myComparer = new MyComparer();
source.OrderBy(s => s, myComparer);

Upvotes: 0

Avi
Avi

Reputation: 1

Below solution works for more than one Caps.

   static void Main(string[] args)
    {

        var names = new List<String>() {
        "access",
        "Addition",
        "ADDition",
        "ADdition",
        "account",
         "base",
        "Brick",
        "zammer",
        "Zilon"
        };


        names.Sort((one, two) =>
        {
            int result = 0;

            var oneArray = one.ToCharArray();
            var twoArray = two.ToCharArray();

            var minLength = Math.Min(oneArray.Length, twoArray.Length) - 1;
            var i = 0;

            while (i < minLength)
            {
                //Diff Letter
                if (Char.ToUpper(one[i]) != Char.ToUpper(two[i]))
                {
                    result = Char.ToUpper(one[i]) - Char.ToUpper(two[i]);
                    break;
                }

                // Same Letter, same case
                if (oneArray[i] == twoArray[i])
                {
                    i++;
                    continue;
                }
                // Same Letter, diff case
                result =  one[i] - two[i];
                break;
            }

            return result;
        });

        foreach (string s in names)
            Console.WriteLine(s);

        Console.WriteLine("done");

Upvotes: 0

MarcinJuraszek
MarcinJuraszek

Reputation: 125660

Proper set of OrderBy/ThenBy calls will do the trick.

  1. Order by first letter lowercased, to get all as and As first, then bs and Bs, etc.
  2. Then by IsLower(firstCharacter), which will get the uppercased items for each letter first.
  3. Then by the entire string.
var sorted = source.OrderBy(s => char.ToLower(s[0]))
                   .ThenBy(s => char.IsLower(s[0]))
                   .ThenBy(s => s)
                   .ToList();

Upvotes: 7

Vignesh Kumar A
Vignesh Kumar A

Reputation: 28413

Try like this

List<string> list = new List<string>();
list.Add("access");
list.Add("Addition");
list.Add("account");
list.Add("base")
list.Add("Brick")
list.Add("zammer")
list.Add("Zilon")
list = list.Where(r => char.IsLower(r[0])).OrderBy(r => r)
      .Concat(list.Where(r => char.IsUpper(r[0])).OrderBy(r => r)).ToList();
for (int i = 0; i < list.Count; i++)
    Console.WriteLine(list[i]);

Upvotes: 0

Related Questions