un tri comme le fait Windows dans l'explorateur, trier pas nom? par date? par type? etc???
Dim images As New List(Of String) images.Add("fichier 51 et aussi 14") images.Add("fichier sans nombre") images.Add("fichier 10") images.Add("fichier 21 test") images.Add("32 fichier test") images.Add("fichier 1") images.Add("fichier 2") images.Add("fichier 3") images.Add("fichier 4") Dim imagesIntermedaires = ( From s In images Let m = Regex.Match(s, "(?<numero>\d+)") Select New With {Key .Texte = s, Key .Cle2Tri = If(m.Success, Convert.ToInt32(m.Groups("numero").Value), Integer.MaxValue)}).OrderBy(Function(x) x.Cle2Tri).ToList() Dim imagesTriees As List(Of String) = imagesIntermedaires.Select(Function(x) x.Texte).ToList() 'si besoin images = imagesTriees
Imports System Imports System.Linq Imports System.Text.RegularExpressions ''' <summary> ''' Ton besoin étant plus compliqué qu'il n'y parraissait initialement ''' je crée une classe dédiée, elle implémente IComparable, interface utlisée par la métode Sort() ''' </summary> Public Class TriMicDundee Implements IComparable(Of TriMicDundee) Public Sub New(ByVal LeTexte As String) Texte = LeTexte End Sub Public Property Texte() As String ''' <summary> ''' Retourne un entier décrivant la comparaison entre cette instance et une autre. ''' 0 c'est égal ''' positif cette occurence est "plus grande", sera triée en direction de la fin de la liste ''' négatif cette occurence est "plus petite", sera triée en direction du début de la liste ''' </summary> ''' <param name="other"></param> ''' <returns></returns> Private Function CompareTo(ByVal other As TriMicDundee) As Integer Implements IComparable(Of TriMicDundee).CompareTo 'on commence par le cas "fichier 2" et "fichier 10" Dim r As New Regex("^(?<debut>[^\d]+)?(?<numero>\d+)") Dim m1 As Match = r.Match(Texte) Dim m2 As Match = r.Match(other.Texte) If m1.Success AndAlso m2.Success AndAlso m1.Groups("debut").Value.TrimEnd(" "c) = m2.Groups("debut").Value.TrimEnd(" "c) Then Return Integer.Parse(m1.Groups("numero").Value).CompareTo(Integer.Parse(m2.Groups("numero").Value)) End If Dim nbreCaractereATester As Integer = Math.Min(Texte.Length, other.Texte.Length) 'on va comparer caractère par caractère Dim speciaux() As Char = {"("c, ")"c, "["c, "]"c, " "c} For i As Integer = 0 To nbreCaractereATester - 1 Dim moi As Char = Texte.Chars(i) Dim autre As Char = other.Texte.Chars(i) If moi = autre Then 'même caractère, pas de comparaison possibble => itération suivante Continue For End If If moi = "."c Then 'on arrive à l'extension, ce moi est plus court, c'est lui qui vaut -1, attention, on fait l'hypotèse qu'il n'y a qu'un seul. dans le nom de fichier Return 1 End If If autre = "."c Then Return -1 End If If Char.IsLetter(moi) AndAlso Char.IsLetter(autre) Then 'deux lettres différentes, on retourne la comparaison de base Return moi.CompareTo(autre) End If If speciaux.Contains(moi) AndAlso speciaux.Contains(autre) Then '2 spéciaux différents, on retourne la comparaison de base Return moi.CompareTo(autre) End If If Char.IsLetterOrDigit(moi) AndAlso speciaux.Contains(autre) Then 'moi n'est pas un spécial et autre si, la comparaison vaut 1 Return 1 End If If speciaux.Contains(moi) AndAlso Char.IsLetterOrDigit(autre) Then 'cas inverse à ci dessus Return -1 End If If Char.IsLetter(moi) AndAlso Char.IsDigit(autre) Then 'moi est une lettre, autre un chiffre, la comparaison 1 Return 1 End If If Char.IsDigit(moi) AndAlso Char.IsLetter(autre) Then 'cas inverse à ci-dessus Return -1 End If 'si on arrive là, on est face à un cas non prévu => à coder donc Throw New Exception("Comparaison non codée") Next i 'si la boucle se termine sans résultat, alors les 2 instances sont identiques Return 0 End Function End Class
Dim images As New List(Of String)() images.Add("fichier 51 et aussi 14.txt") images.Add("fichier sans nombre.txt") images.Add("fichier 10.txt") images.Add("fichier 21 test.txt") images.Add("32 fichier test.txt") images.Add("fichier.txt") images.Add("fichiers.txt") images.Add("fichier 1.txt") images.Add("fichier 2.txt") images.Add("fichier 2.csv") images.Add("(fichier 3.txt") images.Add("[fichier 3.txt") images.Add("]fichier 3.txt") images.Add(")fichier 3.txt") images.Add("a file 4.txt") images.Add("a file9.txt") images.Add("a file[9.txt") images.Add("6a file 4.txt") Dim intermediaires As List(Of TriMicDundee) = images.Select(Function(i) New TriMicDundee(i)).ToList() intermediaires.Sort() Dim imagesTriees As List(Of String) = intermediaires.Select(Function(x) x.Texte).ToList()
Imports System Imports System.Linq Imports System.Text.RegularExpressions ''' <summary> ''' Ton besoin étant plus compliqué qu'il n'y parraissait initialement ''' je crée une classe dédiée, elle implémente IComparable, interface utlisée par la métode Sort() ''' </summary> Public Class TriMicDundee Implements IComparable(Of TriMicDundee) Public Sub New(ByVal LeTexte As String) Texte = LeTexte End Sub Public Property Texte() As String ''' <summary> ''' Retourne un entier décrivant la comparaison entre cette instance et une autre. ''' 0 c'est égal ''' positif cette occurence est "plus grande", sera triée en direction de la fin de la liste ''' négatif cette occurence est "plus petite", sera triée en direction du début de la liste ''' </summary> ''' <param name="other"></param> ''' <returns></returns> Private Function CompareTo(ByVal other As TriMicDundee) As Integer Implements IComparable(Of TriMicDundee).CompareTo 'on commence par le cas "fichier 2" et "fichier 10" Dim r As New Regex("^(?<debut>[^\d]+)?(?<numero>\d+)") Dim m1 As Match = r.Match(Texte) Dim m2 As Match = r.Match(other.Texte) If m1.Success AndAlso m2.Success AndAlso m1.Groups("debut").Value.TrimEnd(" "c) = m2.Groups("debut").Value.TrimEnd(" "c) Then Return Integer.Parse(m1.Groups("numero").Value).CompareTo(Integer.Parse(m2.Groups("numero").Value)) End If Dim nbreCaractereATester As Integer = Math.Min(Texte.Length, other.Texte.Length) 'on va comparer caractère par caractère Dim speciaux() As Char = {"("c, ")"c, "["c, "]"c, " "c} For i As Integer = 0 To nbreCaractereATester - 1 Dim moi As Char = Texte.Chars(i) Dim autre As Char = other.Texte.Chars(i) If moi = autre Then 'même caractère, pas de comparaison possibble => itération suivante Continue For End If If moi = "."c Then 'on arrive à l'extension, ce moi est plus court, c'est lui qui vaut -1, attention, on fait l'hypotèse qu'il n'y a qu'un seul. dans le nom de fichier If autre = " "c Then 'sauf si autre est un espace Return 1 End If Return -1 End If If autre = "."c Then 'cas inverse à ci-dessus If moi = " "c Then Return -1 End If Return 1 End If If Char.IsLetter(moi) AndAlso Char.IsLetter(autre) Then 'deux lettres différentes, on retourne la comparaison de base Return moi.CompareTo(autre) End If If speciaux.Contains(moi) AndAlso speciaux.Contains(autre) Then '2 spéciaux différents, on retourne la comparaison de base Return moi.CompareTo(autre) End If If Char.IsLetterOrDigit(moi) AndAlso speciaux.Contains(autre) Then 'moi n'est pas un spécial et autre si, la comparaison vaut 1 Return 1 End If If speciaux.Contains(moi) AndAlso Char.IsLetterOrDigit(autre) Then 'cas inverse à ci dessus Return -1 End If If Char.IsLetter(moi) AndAlso Char.IsDigit(autre) Then 'moi est une lettre, autre un chiffre, la comparaison 1 Return 1 End If If Char.IsDigit(moi) AndAlso Char.IsLetter(autre) Then 'cas inverse à ci-dessus Return -1 End If 'si on arrive là, on est face à un cas non prévu => à coder donc Throw New Exception("Comparaison non codée") Next i 'si la boucle se termine sans résultat, alors les 2 instances sont identiques Return 0 End Function Public Shared Function TrierListe(Liste As List(Of String)) As List(Of String) Dim intermediaires As List(Of TriMicDundee) = Liste.Select(Function(i) New TriMicDundee(i)).ToList() intermediaires.Sort() Return intermediaires.Select(Function(x) x.Texte).ToList() End Function End Class
Dim images As New List(Of String)() images.Add("fichier 51 et aussi 14.txt") images.Add("fichier sans nombre.txt") images.Add("fichier 10.txt") images.Add("fichier 21 test.txt") images.Add("32 fichier test.txt") images.Add("fichier.txt") images.Add("fichiers.txt") images.Add("fichierstxt") images.Add("fichier 1.txt") images.Add("fichier 2.txt") images.Add("fichier 2.csv") images.Add("(fichier 3.txt") images.Add("[fichier 3.txt") images.Add("]fichier 3.txt") images.Add(")fichier 3.txt") images.Add("a file 4.txt") images.Add("a file9.txt") images.Add("a file[9.txt") images.Add("6a file 4.txt") Dim imagesTriees As List(Of String) = TriMicDundee.TrierListe(images)
15 mars 2018 à 18:11
Image 1
Image 2
Image 3
...
Image 10
Image 11
Contrairement à un ordre alphabétique qui ferai :
Image 1
Image 10
Image 11
Image 2
...
15 mars 2018 à 18:39
15 mars 2018 à 19:32
15 mars 2018 à 20:23
15 mars 2018 à 20:39