Results 1 to 8 of 8

Thread: [RESOLVED] String Sorting

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Sep 2010
    Posts
    230

    Resolved [RESOLVED] String Sorting

    I have a list of strings lets say the items are like this

    item_1
    item_2
    item_4
    item_10
    item_8
    item_11


    if i do list.sort() i get the following

    item_1
    item_10
    item_11
    item_2
    item_4
    item_8


    Somehow i need to get these in order numerically but im dealing with strings not numbers.

  2. #2
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,687

    Re: String Sorting

    yeah, that's an effect of strings... the only way to combat it is to pad with 0's....
    so your list looks like this:
    item_01
    item_10
    item_11
    item_02
    item_04
    item_08

    then sort it:
    item_01
    item_02
    item_04
    item_08
    item_10
    item_11

    That's assuming that you have control over the strings.

    -tg


    edit - strike that... it isn't the ONLY way... but it's usually the easiest... there maybe other ways by implementing your own sorter (somethign I don't have experience with, but others here do) which could break the string up, then return results based on the numerical portion. Bit more work to setup, but probably more elegant, and if the string are not in your control, propbably your best bet.
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  3. #3
    Hyperactive Member jasonwucinski's Avatar
    Join Date
    Mar 2010
    Location
    Pittsburgh
    Posts
    452

    Re: String Sorting

    thats because they are being sorted as if they were strings, not as integers. If this were an array or collection you could have two "columns" one with the string value the other with its corresponding integer value. then sort on the integer value. example is using a sorted dictionary:

    Code:
    Dim myCollection As New SortedDictionary(Of String, Integer)
    myCollection.add("item_1", 1)
    myCollection.add("item_2", 2)
    if i was able to help, rate my post!

  4. #4
    Frenzied Member MattP's Avatar
    Join Date
    Dec 2008
    Location
    WY
    Posts
    1,227

    Re: String Sorting

    For natural sorting you'll need to implement your own IComparer(Of String).

    vb.net Code:
    1. Imports System.Text.RegularExpressions
    2.  
    3. Public Class NaturalComparer
    4.     Implements IComparer(Of String)
    5.  
    6.     Private _pos As Integer
    7.     Private ReadOnly _order As Integer
    8.  
    9.     Public Sub New(Optional Ascending As Boolean = True)
    10.         _order = If(Ascending, 1, -1)
    11.     End Sub
    12.  
    13.     Private Shared Function RegexSplit(ByVal s As String) As String()
    14.         Return Regex.Split(s, "(\d+)", RegexOptions.IgnoreCase)
    15.     End Function
    16.  
    17.     Private Shared Function GetEmptyStrings() As Predicate(Of String)
    18.         Return Function(s) String.IsNullOrEmpty(s)
    19.     End Function
    20.  
    21.     Public Function Compare(x As String, y As String) As Integer Implements IComparer(Of String).Compare
    22.         Dim left As New List(Of String)(RegexSplit(x))
    23.         Dim right As New List(Of String)(RegexSplit(y))
    24.  
    25.         left.RemoveAll(GetEmptyStrings())
    26.         right.RemoveAll(GetEmptyStrings())
    27.  
    28.         _pos = 0
    29.         For Each x In left
    30.             If y.Count > _pos Then
    31.                 If Not Decimal.TryParse(x, Nothing) AndAlso Not Decimal.TryParse(right(_pos), Nothing) Then
    32.                     Dim result As Integer = String.Compare(x, right(_pos), True)
    33.                     If result <> 0 Then
    34.                         Return result * _order
    35.                     Else
    36.                         _pos += 1
    37.                     End If
    38.                 ElseIf Decimal.TryParse(x, Nothing) AndAlso Not Decimal.TryParse(right(_pos), Nothing) Then
    39.                     Return -1 * _order
    40.                 ElseIf Not Decimal.TryParse(x, Nothing) AndAlso Decimal.TryParse(right(_pos), Nothing) Then
    41.                     Return 1 * _order
    42.                 Else
    43.                     Dim result = Decimal.Compare(Decimal.Parse(x), Decimal.Parse(right(_pos)))
    44.                     If result = 0 Then
    45.                         _pos += 1
    46.                     Else
    47.                         Return result * _order
    48.                     End If
    49.                     End If
    50.             Else
    51.                     Return -1 * _order
    52.             End If
    53.         Next
    54.  
    55.         Return _order
    56.     End Function
    57. End Class

    Here's a small example:

    vb.net Code:
    1. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    2.         Dim itemList As New List(Of String) From {"item_1", "item_2", "item_4", "item_10", "item_8", "item_11"}
    3.         itemList.Sort(New NaturalComparer(True))
    4.     End Sub

    You could also use: pinvoke strcmplogicalw
    This pattern in common to all great programmers I know: they're not experts in something as much as experts in becoming experts in something.

    The best programming advice I ever got was to spend my entire career becoming educable. And I suggest you do the same.

  5. #5
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,108

    Re: String Sorting

    Another thing to consider is whether those strings work best as strings. I was working on a similar issue where the strings in question were names that included numbers in them. I sometimes needed to sort the numbers, sometimes the strings, and usually a combination of both. At first I went with the approach that MattP showed. However, as the problem evolved, I determined that the names had to be generated dynamically, and no custom sorter would necessarily work for all the variations that were desired. What I ended up doing was turning the names into a small class that had a string portion, a number portion....another string portion, and finally an ordinal. The class had .ToString overloaded, so that I could get the whole name back out so that it looked nice, but I could do some pretty complex sorting. Often I sorted by the number and the second string, but I could also sort by the ordinal, even though that wasn't visible. That allowed for a huge variety of sorted results.
    My usual boring signature: Nothing

  6. #6
    Lively Member SNIPER.PS's Avatar
    Join Date
    Dec 2009
    Posts
    96

    Arrow Re: String Sorting

    Hello

    Another Easy Solution By LINQ

    Code:
    Dim Lst = (From Item As String In ListBox1.Items Select Item Order By Val(Item.Split("_")(1)) Ascending).ToArray
    ListBox1.Items.Clear()
    ListBox1.Items.AddRange(Lst)
    All The Best

    Mohammad Farah
    الحمد لله

  7. #7
    Frenzied Member MattP's Avatar
    Join Date
    Dec 2008
    Location
    WY
    Posts
    1,227

    Re: String Sorting

    Quote Originally Posted by SNIPER.PS View Post
    Hello

    Another Easy Solution By LINQ

    Code:
    Dim Lst = (From Item As String In ListBox1.Items Select Item Order By Val(Item.Split("_")(1)) Ascending).ToArray
    ListBox1.Items.Clear()
    ListBox1.Items.AddRange(Lst)
    All The Best

    Mohammad Farah
    This makes the assumption that everything before the underscore will be the same. If the list contains 2 items abc_5 and xyz_1 natural sorting would have the abc_5 first.
    This pattern in common to all great programmers I know: they're not experts in something as much as experts in becoming experts in something.

    The best programming advice I ever got was to spend my entire career becoming educable. And I suggest you do the same.

  8. #8
    Lively Member SNIPER.PS's Avatar
    Join Date
    Dec 2009
    Posts
    96

    Arrow Re: String Sorting

    Quote Originally Posted by MattP View Post
    This makes the assumption that everything before the underscore will be the same. If the list contains 2 items abc_5 and xyz_1 natural sorting would have the abc_5 first.
    Hello

    Thanks , You are right .. and the code after edited will be

    Code:
    Dim Lst = (From Item As String In ListBox1.Items Select Item Order By Item.Split("_")(0) Ascending, Val(Item.Split("_")(1)) Ascending).ToArray
    ListBox1.Items.Clear()
    ListBox1.Items.AddRange(Lst)
    All The Best

    Mohammad Farah
    الحمد لله

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width