-
Jan 16th, 2013, 11:53 AM
#1
Thread Starter
Member
[RESOLVED] Vb.net 2010 Sort List(of String) : String with Integer
Hello Genius :
can you help me how to sort string in List(of String)
my code is
PHP Code:
Dim _lst As List(Of String) = New List(Of String)({"ob1", "ob5", "ob2", "ob3", "ob33", "ob10", "ob1", "ob11", "ob123", "ob20"})
_lst.Sort()
ListBox1.Items.AddRange(_lst.ToArray)
Result is like :=
PHP Code:
ob1
ob1
ob10
ob11
ob123
ob2
ob20
ob3
ob33
ob5
but i want to result like this :=
PHP Code:
ob1,ob1,ob2,ob3,..........
how to sort like this please help me l'm struggled
Thanks
-
Jan 16th, 2013, 12:02 PM
#2
Re: Vb.net 2010 Sort List(of String) : String with Integer
The fault lies with the strings not with the sorting. Reference codes such as these should always be formatted to be of the same length. So if your highest reference is ob999, your first should be ob001. This requires nothing but a simple alphabetical sort. If you are unable to produce values in this form because your getting them from a third party, for example, you could attempt a sorting algorithm but assuming you want to avoid potential insanity it would be far simpler to reformat the values using string manipulation methods.
As the 6-dimensional mathematics professor said to the brain surgeon, "It ain't Rocket Science!"
Reviews: "dunfiddlin likes his DataTables" - jmcilhinney
Please be aware that whilst I will read private messages (one day!) I am unlikely to reply to anything that does not contain offers of cash, fame or marriage!
-
Jan 16th, 2013, 12:38 PM
#3
Re: Vb.net 2010 Sort List(of String) : String with Integer
You'll need to have a Natural Comparison of the strings to get what you're looking for.
Here's a couple of options.
vb.net Code:
Imports System.Text.RegularExpressions Public Class NaturalComparer Implements IComparer(Of String) Private _pos As Integer Private ReadOnly _order As Integer Public Sub New(Optional Ascending As Boolean = True) _order = If(Ascending, 1, -1) End Sub Private Shared Function RegexSplit(ByVal s As String) As String() Return Regex.Split(s, "(\d+)", RegexOptions.IgnoreCase) End Function Private Shared Function GetEmptyStrings() As Predicate(Of String) Return Function(s) String.IsNullOrEmpty(s) End Function Public Function Compare(x As String, y As String) As Integer Implements IComparer(Of String).Compare Dim left As New List(Of String)(RegexSplit(x)) Dim right As New List(Of String)(RegexSplit(y)) left.RemoveAll(GetEmptyStrings()) right.RemoveAll(GetEmptyStrings()) _pos = 0 For Each x In left If y.Count > _pos Then If Not Decimal.TryParse(x, Nothing) AndAlso Not Decimal.TryParse(right(_pos), Nothing) Then Dim result As Integer = String.Compare(x, right(_pos), True) If result <> 0 Then Return result * _order Else _pos += 1 End If ElseIf Decimal.TryParse(x, Nothing) AndAlso Not Decimal.TryParse(right(_pos), Nothing) Then Return -1 * _order ElseIf Not Decimal.TryParse(x, Nothing) AndAlso Decimal.TryParse(right(_pos), Nothing) Then Return 1 * _order Else Dim result = Decimal.Compare(Decimal.Parse(x), Decimal.Parse(right(_pos))) If result = 0 Then _pos += 1 Else Return result * _order End If End If Else Return -1 * _order End If Next Return _order End Function End Class
Or using Api Methods.
vb.net Code:
Public Class ApiNaturalComparer Implements IComparer(Of String) Private Class NativeMethods Public Declare Unicode Function StrCmpLogicalW Lib "shlwapi.dll" (s1 As String, s2 As String) As Integer End Class Private ReadOnly _order As Integer Public Sub New(Optional IsAscending As Boolean = True) _order = If(IsAscending, 1, -1) End Sub Public Function Compare(x As String, y As String) As Integer Implements IComparer(Of String).Compare Return NativeMethods.StrCmpLogicalW(x, y) * _order End Function End Class
Usage example of both options.
vb.net Code:
Public Class Form1 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Dim MyList = New List(Of String)({"ob1", "ob5", "ob2", "ob3", "ob33", "ob10", "ob1", "ob11", "ob123", "ob20"}) 'MyList.Sort(New NaturalComparer(True)) 'OutputListBox.Items.AddRange(MyList.ToArray()) MyList.Sort(New ApiNaturalComparer(True)) OutputListBox.Items.AddRange(MyList.ToArray()) End Sub End Class
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.
-
Aug 28th, 2013, 03:31 AM
#4
Thread Starter
Member
Re: [RESOLVED] Vb.net 2010 Sort List(of String) : String with Integer
thanQ Mattp ..itz working fine n once again thnx
-
Aug 28th, 2013, 07:15 AM
#5
Re: [RESOLVED] Vb.net 2010 Sort List(of String) : String with Integer
I know it's resolved but another approach with regex. Rather then splitting i think it be more suited to match the number and sort by that.
vb Code:
Imports System.Text.RegularExpressions Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim list = {"ob1", "ob5", "ob2", "ob3", "ob33", "ob10", "ob1", "ob11", "ob123", "ob20"} Dim orderedList = list.OrderBy(Function(n) CInt(New Regex("(?<=.*)\d+").Match(n).Value)).ToArray Me.ListBox1.Items.AddRange(orderedList) End Sub End Class
-
Aug 28th, 2013, 01:16 PM
#6
Re: [RESOLVED] Vb.net 2010 Sort List(of String) : String with Integer
here's my effort. it'll work with any strings in that format (1 or more letters followed by 1 or more digit):
Code:
Imports System.Text.RegularExpressions
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim _lst As List(Of String) = New List(Of String)(New String() {"bc1", "bc5", "bc2", "bc3", "bc33", "bc10", "bc1", "bc11", "bc123", "bc20", "ab1", "ab5", "ab2", "ab3", "ab33", "ab10", "ab1", "ab11", "ab123", "ab20"})
_lst.Sort(New comparer)
ListBox1.Items.AddRange(_lst.ToArray)
End Sub
End Class
Public Class comparer
Implements IComparer(Of String)
Public Function Compare(ByVal x As String, ByVal y As String) As Integer Implements System.Collections.Generic.IComparer(Of String).Compare
Dim matches() As Match = {New Regex("^(?<textPart>[A-Za-z]+)(?<numericPart>\d+)$").Match(x), New Regex("^(?<textPart>[A-Za-z]+)(?<numericPart>\d+)$").Match(y)}
Dim xParts() As String = matches(0).Groups.Cast(Of Group).Skip(1).Select(Function(g) g.Value).ToArray
Dim yParts() As String = matches(1).Groups.Cast(Of Group).Skip(1).Select(Function(g) g.Value).ToArray
If xParts(0) = yParts(0) Then
Return CInt(xParts(1)).CompareTo(CInt(yParts(1)))
Else
Return xParts(0).CompareTo(yParts(0))
End If
End Function
End Class
- Coding Examples:
- Features:
- Online Games:
- Compiled Games:
-
Aug 28th, 2013, 04:03 PM
#7
Re: [RESOLVED] Vb.net 2010 Sort List(of String) : String with Integer
Another attempt supporting sorting of letters.... I'm purposely ignoring the IComparer class.
vb Code:
Imports System.Text.RegularExpressions Public Class Form1 Private Sub SortArray(ByVal list() As String) Me.ListBox1.Items.AddRange( ( From item In list Order By New Regex("[a-z]+").Match(item).Value, CInt(New Regex("(?<=.*)\d+").Match(item).Value) Select item).ToArray ) End Sub End Class
Last edited by ident; Aug 28th, 2013 at 04:22 PM.
-
Aug 29th, 2013, 01:48 AM
#8
Re: [RESOLVED] Vb.net 2010 Sort List(of String) : String with Integer
you wouldn't create a new instance of regex each time like i provided though
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|