Utilisation de sortedlist pour trier une collection de valeurs décomposées de sous valeurs

Soyez le premier à donner votre avis sur cette source.

Snippet vu 5 829 fois - Téléchargée 17 fois


Contenu du snippet

Il s'agit d'un exemple d'utilisation de SortedList réalisé avec VB Express 2010.

L'objectif est de passer en argument un objet Collection composé de chaines de String.
Chaque item (String) de la Collection est composée de plusieurs items.
Chaque item est décomposé par un caratère séparateur, par exemple | (pipe)

Ma Collection est créée avec les informations suivantes :
Eleve chose|mention du coin|12
Eleve machin|pas de mention|5
Eleve truc|mention bidule|19
Eleve du bol|mention a rien|1

je souhaite faire un tri sur la troisième info et obtenir la liste suivante:
Eleve du bol|mention a rien|1
Eleve machin|pas de mention|5
Eleve chose|mention du coin|12
Eleve truc|mention bidule|19

ou obtenir la liste (Collection) inverse :
Eleve truc|mention bidule|19
Eleve chose|mention du coin|12
Eleve machin|pas de mention|5
Eleve du bol|mention a rien|1

Mon objectif est donc d'utiliser un élément de chaque item de ma Collection, comme paramètre d'un trie croissant ou décroissant, comme des notes dans mon exemple.

Source / Exemple :


Imports System.Collections.Generic

Module TrierCollection
#Region "Trier une Collection"

    ' --------------------------------------------------------------------------------------------------
    ' Effectue un trie du contenu de la Collection passé en argument,
    ' avec précision de la position de l'argument de trie :
    '       la valeur de chaque item de la Collection est composée de plusieurs chaines séparées, dont
    '       l'élément qui servira au trie
    '
    Public Function SortThisCollByArgu(ByRef theList As Collection, ByVal thePos As Integer, _
                                            Optional ByVal theSeparator As String = "|", _
                                            Optional ByVal smallToHigh As Boolean = False) As Boolean
        Dim ct As Integer, theInfo() As String
        Dim theSortedList As New SortedList(Of Long, String)

        SortThisCollByArgu = False

        Try
            ' If Not theList Is Nothing Then
            If Not theList Is Nothing Then
                ' Test nombre d'argument en cohérence avec la position de trie
                theInfo = Split(theList(1).ToString, theSeparator)
                If thePos > theInfo.GetUpperBound(0) Then Exit Function

                ' Boucle sur la Collection
                For ct = 1 To theList.Count
                    ' Récupération formatée des informations
                    theInfo = Split(theList(ct).ToString, theSeparator)

                    ' Ajout dans la liste automatiquement triée, de la valeur de trie
                    ' et de la chaine originale
                    Call theSortedList.Add(CLng(theInfo(thePos)), theList(ct).ToString)
                Next

                ' Recréation de la liste pour ajout des valeurs dans l'odre
                Call theList.Clear()

                If smallToHigh = True Then
                    ' Du plus grand au plus petit
                    For ct = theSortedList.Count - 1 To 0 Step -1
                        Call theList.Add(theSortedList.Values(ct))
                    Next
                Else
                    ' Du plus petit au plus grand : par défaut
                    For ct = 0 To theSortedList.Count - 1
                        Call theList.Add(theSortedList.Values(ct))
                    Next
                End If

                SortThisCollByArgu = True
            End If

        Catch Err As Exception
            Call addError(Err.Message)
        End Try
    End Function
#End Region

End Module

Conclusion :


j'utilise SortedList pour créer une liste triée en passant la valeur de trie désignée par la position (thePos) comme Clef et en réinjectant la chaine d'origine comme Valeur (theList(ct).ToString). De ce faite, le parcours de la nouvelle liste (dans un sens ou dans l'autre) permet d'avoir un trie de ma liste d'origine.

Les options de la fonction me permettent d'une part de choisir un séparateur en fonction de la liste d'origine, mais aussi la position qui détermine la valeur du trie.

Cela peut aussi fonctionner avec une chaine de caractères en modifiant la déclaration de theSortedList par SortedList(Of String, String), sans omettre de supprimer la conversion Clng (mais l'éditeur de VB Express donnera une erreur en cas de conversion de type non autorisée).

l'utilisation de theList.Clear() peut tout de même être dangereux, si une exception se produit après, la liste est perdue. Une variante serait de renvoyer une nouvelle liste et non un Boolean.

il y a sans doute d'autres façon plus élégante d'écrite un code de trie d'une Collection, je laisse les autres contributeurs pour compléter cela.

A voir également

Ajouter un commentaire

Commentaires

blq
Messages postés
98
Date d'inscription
vendredi 22 octobre 1999
Statut
Membre
Dernière intervention
13 juin 2016
1 -
Tout en restant dans l'utilisation de SortedList, qui n'est peut-être pas le meilleur choix, j'utilise ContainsKey avant d'ajouter un nouvel élément à la liste. Ce qui me permet de modifier la clef :

ct = 1
originalKey = theKey

Do While theSortedList.ContainsKey(theKey) = True
ct = ct + 1
theKey = originalKey & ct
Loop

Call theSortedList.Add(theKey, theValue)
cs_marcA
Messages postés
12
Date d'inscription
lundi 14 avril 2003
Statut
Membre
Dernière intervention
3 août 2010
-
Dans ce cas, il ne faut pas faire une sortedlist, mais une simple liste et utiliser la fonction sort
List.Sort (New CClassComparer)

Et la classe CComparer est ainsi
Friend Class CClassComparer

' Implements the manual sorting of items by columns.
Implements IComparer(Of CClass)

Public Function Compare(ByVal x As CClass, ByVal y As CClass) As Integer Implements IComparer(Of CClass).Compare

If x.Value > y.Value Then
Return 1
ElseIf x.Value < y.Value Then
Return -1
Else
Return 0
End If

End Function

End Class
donkeises
Messages postés
1
Date d'inscription
jeudi 12 août 2010
Statut
Membre
Dernière intervention
12 août 2010
-
Bonjour,

Pouvez vous m'aider avec mon code! je voudrais utiliser une sortedlist sauf que j'ai des clés identique des fois! comment puis je modifier la fonction sortedlidt
blq
Messages postés
98
Date d'inscription
vendredi 22 octobre 1999
Statut
Membre
Dernière intervention
13 juin 2016
1 -
Une annotation tout de même sur ce code. Je souhaitais juste donner un exemple d'utilisation de SortedList, mais mon exemple à une grosse limitation. Le trie via SortedList implique que les clefs soient uniques, donc une même valeur posera un souci à l'ajout.

Pour améliorer cela, un test peut-être ajouter par vérification de l'existence de la clef (theSortedList.ContainsKey), mais dans mon exemple, cela fausse la valeur de trie. Je ferais mieux la prochaine fois.

' Boucle sur la Collection
For ct = 1 To theList.Count
' Récupération formatée des informations
theInfo = Split(theList(ct).ToString, theSeparator)

' Ajout dans la liste automatiquement triée, de la valeur de trie
' et de la chaine originale : attention la clef doit être unique...
' Donc, il faut l'incrémenter. L'incrément n'a pas d'incidence sur la Chaine d'origine.
' Il y a donc un problème, si trop de clefs de trie identiques...
theSortedValue = CLng(theInfo(thePos))

Do While theSortedList.ContainsKey(theSortedValue) = True
theSortedValue = theSortedValue + 1
Loop

Call theSortedList.Add(theSortedValue, theList(ct).ToString)
Next
cs_marcA
Messages postés
12
Date d'inscription
lundi 14 avril 2003
Statut
Membre
Dernière intervention
3 août 2010
-
Sans utiliser de clé, la List n'a qu'une seule différence par rapport à la collection, c'est que l'on travaille de 0 à n-1. Pour le reste, c'est pareil.

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.