[英]Natural-sort Strings which are in a List(of class)
Unfortunately I have a problem with my code.不幸的是我的代码有问题。 Over the months I have added a few things to my program every now and then.
在这几个月里,我不时地在我的程序中添加了一些东西。 Now the code is a bit "misbuild(t)" and I need your help.
现在代码有点“构建错误(t)”,我需要你的帮助。 I have a program in which there are threads and posts – like in a classic Inte.net forum.
我有一个程序,其中有线程和帖子——就像在经典的 Inte.net 论坛中一样。 A thread can contain multiple posts;
一个线程可以包含多个帖子; a posting contains several images and texts.
一个帖子包含多个图像和文本。 So... You can click on a certain posting in the ListBox and display its images as large as possible.
所以... 您可以单击列表框中的某个帖子并尽可能大地显示其图像。 This is done with a separate form.
这是通过单独的表格完成的。 With 3 different radio buttons I can sort it according to the size of the images (megapixel), or according to the modification date, or according to the file name.
使用 3 个不同的单选按钮,我可以根据图像大小(百万像素)、修改日期或文件名对其进行排序。 To be able to sort by megapixel, I once created an class
Bildeigenschaften
(image properties class).为了能够按百万像素排序,我曾经创建了一个 class
Bildeigenschaften
(图像属性类)。 The sorted_List
is therefore a List(of Bildeigenschaften)
.因此
sorted_List
是一个List(of Bildeigenschaften)
。 Today, I discovered that sorting by name is unlike sorting by name in Windows Explorer.今天发现按名字排序和Windows Explorer按名字排序不一样。 Windows Explorer sorts Natural (as I found out), so this is how it is
Windows 资源管理器排序自然(正如我发现的),所以它是这样的
ABC9
ABC9
ABC10
ABC10
instead of like in my program而不是像我的程序
ABC10
ABC10
ABC9
ABC9
. . So I got some code that sorts "Natural".
所以我得到了一些排序“自然”的代码。 How do I get this linked now?
我现在如何获得此链接?
the Form表格
Private Property List_of_class_Bildeigenschaften As New List(Of Bildeigenschaften)
Private sorted_List As List(Of Bildeigenschaften)
'--------------------
Private Sub RadioButton2_CheckedChanged(sender As Object, e As EventArgs) Handles RadioButton2.CheckedChanged
If RadioButton2.Checked Then
sorted_List = List_of_class_Bildeigenschaften.OrderBy(Function(o) o._FileInfo.Name).ToList()
If CheckBox1.Checked Then
sorted_List.Reverse()
End If
End If
If CheckBox1.Checked Then
sorted_List.Reverse()
End If
End Sub
'--------------------
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 As Integer = 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
Class Bildeigenschaften Class 教育局
Public NotInheritable Class Bildeigenschaften
Public Megapixels As UInt32
Public Bild As System.Drawing.Bitmap
Public _FileInfo As IO.FileInfo
Public Sub New(ByVal Breite As UInt32, ByVal Hoehe As UInt32, ByVal Bild As Bitmap, ByVal einefileinfo As IO.FileInfo)
Me.Megapixels = Breite * Hoehe
Me.Bild = Bild
Me._FileInfo = einefileinfo
End Sub
End Class
You can use Windows' StrCmpLogicalW
that is also used by the explorer:您可以使用资源管理器也使用的 Windows 的
StrCmpLogicalW
:
Public Class NaturalSortComparer
Implements IComparer(Of String)
Declare Unicode Function StrCmpLogicalW Lib "shlwapi.dll" ( _
ByVal s1 As String, _
ByVal s2 As String) As Int32
Public Function Compare(ByVal x As String, ByVal y As String) As Integer Implements System.Collections.Generic.IComparer(Of String).Compare
Return StrCmpLogicalW(x, y)
End Function
End Class
For example:例如:
Dim list = New List(Of String)
list.Add("ABC10")
list.Add("ABC9")
Console.WriteLine(String.Join(",", list))
list.Sort(New NaturalSortComparer())
Console.WriteLine(String.Join(",", list))
Output: Output:
ABC10,ABC9
ABC9,ABC10
You can also use it with LINQ:您也可以将它与 LINQ 一起使用:
list = list.OrderBy(Function(s) s, New NaturalSortComparer()).ToList()
That answers also your question how to install your comparer in the query:这也回答了您如何在查询中安装比较器的问题:
sorted_List = List_of_class_Bildeigenschaften.OrderBy(Function(o) o._FileInfo.Name, New NaturalComparer()).ToList()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.