Search code examples
c#arraysstringsortingalphabetical

C# Sort string array alphabetically taking care of putting strings which start with capital letter first. first


1) There is a Kata which states to order all string in a string array, then take the first word and add *** between each letter: https://www.codewars.com/kata/sort-and-star

2) For example:

(1) It is given:

bitcoin
take
over
the
world
maybe
who
knows
perhaps

(2) After ordering it:

bitcoin
knows
maybe
over
perhaps
take
the
who
world

(3) The return result is:

b***i***t***c***o***i***n

3) However the difficulty I am facing is the following: How we can express 'order first the words which start with capital letter'?

4) I have tried the following code:

using System;
public class Kata
{
  public static string TwoSort(string[] s)
  {
  foreach(string str in s){
    Console.WriteLine(str);
  }
  Console.WriteLine("");
  Array.Sort(s);
  foreach(string str in s){
    Console.WriteLine(str);
  }

  Console.WriteLine("");

  string firstWord = s[0];
  string result = "";


  foreach(char letter in firstWord){
    result += letter + "***";

  }
  Console.WriteLine(result.Substring(0, result.Length - 3));
    return result.Substring(0, result.Length - 3);
  }  
}

5) For example:

(1) It is given the following array:

Lets
all
go
on
holiday
somewhere
very
cold

(2) After ordering it:

all
cold
go
holiday
Lets
on
somewhere
very

(3) Current wrong result:

a***l***l

(4) Expected correct result:

L***e***t***s

I have also read:

how to sort a string array by alphabet?

Sorting an array alphabetically in C#


Solution

  • You should specify the comparer, e.g. (Linq solution):

      string[] source = new string[] {
        "Lets",
        "all",
        "go",
        "on",
        "holiday",
        "somewhere",
        "very",
        "cold",
      };
    
      // StringComparer.Ordinal: order by Ascii values; capital letters < small letters 
      var ordered = source
        .OrderBy(item => item, StringComparer.Ordinal);
    
      Console.Write(string.Join(", ", ordered));
    

    Outcome:

      Lets, all, cold, go, holiday, on, somewhere, very
    

    To obtain the desired outcome (in case you insist on ordering), you can put

      var result = string.Join("***", source
        .OrderBy(item => item, StringComparer.Ordinal) 
        .First()
        .Select(c => c)); // <- turn string into IEnumerable<char> 
    
      Console.Write(result);
    

    Outcome:

      L***e***t***s
    

    In case you want to keep on using your current code, change Array.Sort(s); into

      Array.Sort(s, StringComparer.Ordinal);