Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. NumericString Sort

NumericString Sort

Scheduled Pinned Locked Moved C#
algorithms
5 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • U Offline
    U Offline
    User 10560398
    wrote on last edited by
    #1

    Hi All, I have a column in my table which contains a string that can have data like below: ABC 1 ABC 10 ABC 2 ABC 100 ADBCDEF - 1 ADBCDEF - 10 ADBCDEF - 3 I need the output to be like: ABC 1 ABC 2 ABC 10 ABC 100 ADBCDEF - 1 ADBCDEF - 3 ADBCDEF - 10 When i apply dataview.sort, it gives output as: ABC 1 ABC 10 ABC 100 ABC 2 I need to sort my datagrid with the above column. Can anyone provide a sorting algorithm to solve this. Thanks Sai

    V L D R 4 Replies Last reply
    0
    • U User 10560398

      Hi All, I have a column in my table which contains a string that can have data like below: ABC 1 ABC 10 ABC 2 ABC 100 ADBCDEF - 1 ADBCDEF - 10 ADBCDEF - 3 I need the output to be like: ABC 1 ABC 2 ABC 10 ABC 100 ADBCDEF - 1 ADBCDEF - 3 ADBCDEF - 10 When i apply dataview.sort, it gives output as: ABC 1 ABC 10 ABC 100 ABC 2 I need to sort my datagrid with the above column. Can anyone provide a sorting algorithm to solve this. Thanks Sai

      V Offline
      V Offline
      V 0
      wrote on last edited by
      #2

      Tricky case. I would split the numerical part and text part, but keep them in one class. * Then you can order by the text first and with the numeric part second through a custom function implementing some sorting algorithm. * or group first by text and with an array of integer attached to them like "ABC" with { 1, 2, 10, 100 } eg. Then you can order the class with the text property and print the concatenated text/integer ordered by the numerical part. * If they can stay split in the dataview you could just do like in a database“s order by clause, simplifying things a bit. Hope this helps.

      V.
      (MQOTD rules and previous solutions)

      OriginalGriff wrote:

      V is absolutely right

      1 Reply Last reply
      0
      • U User 10560398

        Hi All, I have a column in my table which contains a string that can have data like below: ABC 1 ABC 10 ABC 2 ABC 100 ADBCDEF - 1 ADBCDEF - 10 ADBCDEF - 3 I need the output to be like: ABC 1 ABC 2 ABC 10 ABC 100 ADBCDEF - 1 ADBCDEF - 3 ADBCDEF - 10 When i apply dataview.sort, it gives output as: ABC 1 ABC 10 ABC 100 ABC 2 I need to sort my datagrid with the above column. Can anyone provide a sorting algorithm to solve this. Thanks Sai

        L Offline
        L Offline
        Lost User
        wrote on last edited by
        #3

        It depends. In the general case, that's called Natural Sort, which isn't one specific algorithm but a family of different ways to compare strings such that their order looks "natural". That's an inherently ambiguous requirement, so there are many different implementations. It gets particularly difficult if you want to include dates. If it's just about strings that end in some number of digits, there is an easy ad-hoc solution for that.

        1 Reply Last reply
        0
        • U User 10560398

          Hi All, I have a column in my table which contains a string that can have data like below: ABC 1 ABC 10 ABC 2 ABC 100 ADBCDEF - 1 ADBCDEF - 10 ADBCDEF - 3 I need the output to be like: ABC 1 ABC 2 ABC 10 ABC 100 ADBCDEF - 1 ADBCDEF - 3 ADBCDEF - 10 When i apply dataview.sort, it gives output as: ABC 1 ABC 10 ABC 100 ABC 2 I need to sort my datagrid with the above column. Can anyone provide a sorting algorithm to solve this. Thanks Sai

          D Offline
          D Offline
          DaveyM69
          wrote on last edited by
          #4

          This works the way you have described. It may not be very efficient so you may want to optimise it somewhat:

          public static int Compare(string first, string second)
              {
                  if (object.ReferenceEquals(first, second))
                      return 0;
                  if (object.ReferenceEquals(null, first)) // second cannot be null
                      return -1;
                  // neither string can be null
                  char\[\] digits = new char\[\] { '0', '1', '2', '3', '4', '5', '6', '7', '8','9' };
                  int firstDigitIndex = first.IndexOfAny(digits);
                  int secondDigitIndex = second.IndexOfAny(digits);
                  string firstLhs = firstDigitIndex == -1 ? first : first.Substring(0, firstDigitIndex);
                  string secondLhs = secondDigitIndex == -1 ? second : second.Substring(0, firstDigitIndex);
                  int result = firstLhs.CompareTo(secondLhs);
                  if (result == 0)
                  {
                      // left hand sides are equal so sort on numeric part
                      int firstInteger = 0;
                      int secondInteger = 0;
                      if (firstDigitIndex > -1)
                          int.TryParse(first.Substring(firstDigitIndex), out firstInteger);
                      if (secondDigitIndex > -1)
                          int.TryParse(second.Substring(secondDigitIndex), out secondInteger);
                      result = firstInteger.CompareTo(secondInteger);
                  }
                  return result;
              }
          

          Test:

              SortAndWriteList(new List(new string\[\] { "ABC 1", "ABC 10", "ABC 2", "ABC 100" }));
              Console.WriteLine();
              SortAndWriteList(new List(new string\[\] { "ADBCDEF - 1", "ADBCDEF - 10", "ADBCDEF - 3" }));
              Console.WriteLine();
              Console.ReadKey();
          
              private static void SortAndWriteList(List list)
              {
                  if (list != null)
                  {
                      list.Sort(new Comparison(Compare));
                      foreach (string item in list)
                          Console.WriteLine(item);
                  }
              }
          

          Result:

          ABC 1
          ABC 2
          ABC 10
          ABC 100

          ADBCDEF - 1
          ADBCDEF - 3
          ADBCDEF - 10

          Dave
          Binging is like googling, it just feels dirtier. Please take your VB.NET out of our nice case sensitive forum. Astonish us. Be exceptional. (

          1 Reply Last reply
          0
          • U User 10560398

            Hi All, I have a column in my table which contains a string that can have data like below: ABC 1 ABC 10 ABC 2 ABC 100 ADBCDEF - 1 ADBCDEF - 10 ADBCDEF - 3 I need the output to be like: ABC 1 ABC 2 ABC 10 ABC 100 ADBCDEF - 1 ADBCDEF - 3 ADBCDEF - 10 When i apply dataview.sort, it gives output as: ABC 1 ABC 10 ABC 100 ABC 2 I need to sort my datagrid with the above column. Can anyone provide a sorting algorithm to solve this. Thanks Sai

            R Offline
            R Offline
            Richard Deeming
            wrote on last edited by
            #5

            If you want to duplicate the natural sort order used in Windows Explorer, the simplest option is to P/Invoke the StrCmpLogicalW function[^] from shlwapi.dll:

            public class LogicalStringComparer : IComparer
            {
            [DllImport("shlwapi.dll", CharSet=CharSet.Unicode, ExactSpelling=true, SetLastError=true)]
            private static extern int StrCmpLogicalW(string x, string y);

            public int Compare(string x, string y)
            {
                return StrCmpLogicalW(x, y);
            }
            

            }

            StrCmpLogicalW on MSDN[^]


            "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups