0

I have an example string:

"60 seconds,1;120 seconds,2;180 seconds,3;15 seconds,15;20 seconds,20;30 seconds,30"

I'd like to sort it by the first number only. So after sorting, it'll look like:

"15 seconds,15;20 seconds,20;30 seconds,30;60 seconds,1;120 seconds,2;180 seconds,3"

Some limitations: I can't hard code anything. I've created example code to demonstrate my solution so far. Basically, I create 2 string arrays and 1 int array. The first string array takes the string and splits it by the semicolon. The second string array is a middle man array. The int array is the middle man array converted to int. I use the int array as a reference to sort my first string array using Array.sort Here is my example code:

using System;
using System.Linq;              
using System.Text.RegularExpressions;

public class Program
{
    public static void Main()
    {
        string myExampleString = "60 seconds,1;120 seconds,2;180 seconds,3;15 seconds,15;20 seconds,20;30 seconds,30";
        string mySortedString = "";
        
        // Count the number of semicolons and + 1 to get arraySize
        int arraySize = myExampleString.Count(f => (f == ';')) + 1;

        // To hold our original string, split by the ';'
        String[] stringArray = new String[arraySize];
        
        // Our middle man array to make sorting easier
        String[] organizedStringArray = new String[arraySize];
        
        // Our middle man array converted to int
        int[] intArray = new int[arraySize];
        
        // Create the stringArray without the semicolons
        stringArray = myExampleString.Split(';');
        
        for(int i=0; i<arraySize; i++)
        {
            // Our stringArray elements: 
            /*
                60 seconds,1
                120 seconds,2
                180 seconds,3
                15 seconds,15
                20 seconds,20
                30 seconds,30
            */
            
            // Let's make our organizedStringArray elements:
            /*
                60
                120
                180
                15
                20
                30
            */
            Regex regex = new Regex(" .*");
            organizedStringArray[i] = regex.Replace(stringArray[i], "");    
        }
        
        // Convert the middleman array to ints
        intArray = Array.ConvertAll(organizedStringArray, s => int.Parse(s));
        
        // Use the sort function to sort our orignal stringArray, using intArray as the reference
        Array.Sort(intArray, stringArray);
        
        // Append the results into mySortedString
        for(int i=0; i<arraySize; i++)
        {
            if(i < arraySize - 1 )
            {
                mySortedString += stringArray[i] + ";";
            }
            else
            {
                mySortedString += stringArray[i];
            }
        }
        
        Console.WriteLine(mySortedString);
    }
}
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
Tim
  • 478
  • 4
  • 15
  • Ignoring the part where you for some reason wrote `String.Join` by hand in the worst known way (never build large string with string concatenation) the answers are covered by "natural sort" question. – Alexei Levenkov Dec 04 '20 at 21:01

1 Answers1

2

You could use Linq to do a lot of the heavy lifting. I'd split the string by ; to get an array, then sort this array with a custom comparer that splits the string by ' ', takes the first part and parses it to an int, and then join that array back with ;s:

using System;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        string myExampleString = "60 seconds,1;120 seconds,2;180 seconds,3;15 seconds,15;20 seconds,20;30 seconds,30";
        string sorted = String.Join(";", myExampleString.Split(';').OrderBy(s => int.Parse(s.Split(' ')[0])));
        
        Console.WriteLine(sorted);
    }
}
Mureinik
  • 297,002
  • 52
  • 306
  • 350
  • Hey! Thanks for your comment. Your solution is giving me an error at the myExampleString.Split(';'): cannot convert from 'System.Ling.IOrderedEnumerable' to 'string' – Tim Dec 04 '20 at 20:42
  • @Tim care to elaborate? This seems to work just fine: https://dotnetfiddle.net/x3CtKz – Mureinik Dec 04 '20 at 20:44
  • @Tim come to think about it, perhaps you're using a slighter older C# version than me. What version of C#/.NET are you using? – Mureinik Dec 04 '20 at 20:44
  • I'm using .NET 4.7.2 – Tim Dec 04 '20 at 20:48
  • 1
    @Tim my bad - .NET 4.7.2 doesn't allow joining on a `char`, only on a `string`. I've edited my answer to comply with .NET 4.7.2 too. – Mureinik Dec 04 '20 at 20:52