IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB.NET Discussion :

Sort() et List(Of List(String))


Sujet :

VB.NET

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Ingénieur avant-vente
    Inscrit en
    Mai 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur avant-vente
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 5
    Par défaut Sort() et List(Of List(String))
    Bonjour,

    Je souhaiterais trier une liste en fonction d'une valeur d'une liste imbriquée.
    J'ai une liste "Nomenclature" qui est une list(Of List(Of String))

    La liste imbriquée est composé de 2 colonnes: Désignation et Longueur
    La Nomenclature est composé de plusieurs "lignes".

    J'aimerais trier ma nomenclature en fonction de la seconde colonne (la longueur), le soucis c'est qu'avec sort() je ne sais pas comment m'y prendre. J'arrive à le faire sur une liste simple, mais dans mon cas je ne vois pas comment selectionner ma colonne longueur

    Initialement j'avais fait ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
               Do While ListNomenclatureTriée.Count <> ListNomenclature.Count 'Loop Tant que le nombre de barre triées et différent du nombre de barre initial
               For i As Integer = 0 To ListNomenclature.Count - 1
                    Dim BomRowLigne As List(of String) = ListNomenclature.Item(i)
                    Dim LongueurBrute As String = BomRowLigne.Item(2)
                    LongueurBrute = Left(LongueurBrute, Len(LongueurBrute) - 2) 'Suppression des "mm"
                    LongueurBrute = Replace(LongueurBrute, ",", "")    'Suppression Virgule
                    LongueurBrute = LongueurBrute / 10               'Mise en mm
                    Dim LongueurActuelle As Double = Convert.ToDouble(LongueurBrute)
                    If LongueurActuelle > PlusGrandeLongueur And LongueurActuelle < DerniereLongeurInscrite Then
                        PlusGrandeLongueur = LongueurActuelle
                        PlusGrandeLongueurIndex = i
                    End If
                Next
                If PlusGrandeLongueur <= DerniereLongeurInscrite Then
                    LigneAAjouter = ListNomenclature.Item(2)
                    ListNomenclatureTriée.Add(LigneAAjouter)
                    DerniereLongeurInscrite = PlusGrandeLongueur
                    PlusGrandeLongueur = 0
                End If
            Loop
    Ce code marche bien sauf quand j'ai plusieurs lignes avec la même longueur, chose qui peut arriver...
    Merci d'avance pour les pistes ;-)

  2. #2
    Membre Expert Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Par défaut réponse
    Bonjour,

    Il y a de l'idée dans algorithme, tu récupères le plus grand à chaque fois et tu te créer une autre liste au fur et à mesure.
    Mais, il y a quand même un bug.

    Quand tu fais LongueurActuelle < DerniereLongeurInscrite, c'est ce qui te permets de prendre à chaque fois une longueur inférieur à la précédente, pour ne pas reprendre les anciennes valeurs les plus grandes, mais comme tu l'as remarqué, si il y a un doublon, elle est ignorée.

    Il n'y a qu'un solution pour adapté ton algorithme finalement, c'est :

    1) d'enlever "LongueurActuelle < DerniereLongeurInscrite" pour pas que les doublons soient zappés.
    2) d'enlever les valeurs de l'ancienne liste que tu ajoutes au fur et à mesure à ta nouvelle liste

    pour ce 2, le truc, c'est que tu boucles sur l'index... Donc enlever des éléments au fur et à mesure va te faire une erreur, tu auras des index plus grands que la taille de la liste, il faut donc boucler plutôt sur le fait qu'il te reste des éléments à trier.

    Donc un truc du genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    While ListNomenclature.Count > 0
     
         'Tu trouve l'index du plus grand plus grand (PlusGrandeLongueurIndex )
          For i As Integer = 0 To ListNomenclature.Count - 1
                    Dim BomRowLigne As List(of String) = ListNomenclature.Item(i)
                    Dim LongueurBrute As String = BomRowLigne.Item(2)
                    LongueurBrute = Left(LongueurBrute, Len(LongueurBrute) - 2) 'Suppression des "mm"
                    LongueurBrute = Replace(LongueurBrute, ",", "")    'Suppression Virgule
                    LongueurBrute = LongueurBrute / 10               'Mise en mm
                    Dim LongueurActuelle As Double = Convert.ToDouble(LongueurBrute)
                    If LongueurActuelle > PlusGrandeLongueur Then
                        PlusGrandeLongueur = LongueurActuelle
                        PlusGrandeLongueurIndex = i
                    End If
          Next
     
    'tu ajoutes à ta nouvelle liste
    LigneAAjouter = ListNomenclature.Item(PlusGrandeLongueurIndex )
    ListNomenclatureTriée.Add(LigneAAjouter)
     
    'tu supprimes de l'ancienne liste
    ListNomenclature.RemoveAt(PlusGrandeLongueurIndex )
     
     
    End While

  3. #3
    Membre émérite
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2012
    Messages
    337
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2012
    Messages : 337
    Par défaut
    Bonjour,

    Personnellement, je me serai créé un objet "Barre" avec les propriétés Désignation et Longueur et un objet Nomenclature qui hérite de List(Of Barre). Ensuite on surcharge la méthode .Sort() de l'objet Nomenclature et c'est fini. Enfin du moins pour ce que j'ai compris de l'énoncé

    Le code pour exemple :

    L'objet Barre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Public Class Barre
        Public Overridable Property Désignation As String = String.Empty
        Public Overridable Property Longueur As Double = 0
     
        Public Sub New(ByVal _Désignation As String, ByVal _Longueur As Double)
            Me.Désignation = _Désignation
            Me.Longueur = _Longueur
        End Sub
    End Class
    L'objet Nomenclature :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Public Class Nomenclature
        Inherits List(Of Barre)
     
        Overloads Function Sort()
            Dim result = From el As Barre In Me Select el Order By el.Longueur Descending
     
            Return result.ToList
        End Function
     
    End Class
    Pour tester, j'ai créé une boucle qui me remplit la nomenclature, mis un bouton pour trier la nomenclature et l'affichage se fait dans un datagridview :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    Public Class Form1
        Dim MaNomenclature As New Nomenclature
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            'Tri de la liste et affectation à la source du datagridview
            Me.DataGridView1.DataSource = MaNomenclature.Sort()
     
        End Sub
     
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            'Remplissage de la nomenclature
            For i As Integer = 0 To 50
                MaNomenclature.Add(New Barre("Barre " & i + 1, i * 20))
            Next
            Me.DataGridView1.DataSource = MaNomenclature
        End Sub
    End Class
    Ca ne répond peut être pas bien à votre question puis que je n'utilise pas de list(Of List(Of String)) mais je trouve que c'est beaucoup plus simple.

    PS : C'est pas bien de me copier en créant un logiciel de mise en barre

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Ingénieur avant-vente
    Inscrit en
    Mai 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur avant-vente
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 5
    Par défaut
    Grand merci à tout les deux pour vos réponses et la réactivité !

    @mactwist69
    J'utilise cette solution ailleurs mais je voulais éviter de trop tripoter la liste initial parce que je l'a réutilise ailleurs. Bon tu me diras je peux toujours faire une copie mais bon :-D. merci en tout cas ;-)

    @Rainui
    J'aime bien ta solution, enfaite j'ai bien simplifier l'énoncé et c'est pas vraiment une list (of list (of String)) mais bien une liste d'objets (des lignes), qui sont eux même des lists (of string).
    Du coup ça colle parfaitement avec la suite de ta solution

    PS : C'est pas bien de me copier en créant un logiciel de mise en barre
    Je fais pas un logiciel, juste une macro qui s'ajoute à un logiciel, à but non lucratif en plus :-D J'ai bien l'algo de mise en barre en tête mais je galère un peut avec le transite et la mise en forme des informations Mais je serais ravi d'échanger une fois que ça sera terminer sur les résultats niveau performance et pertinence de la solution trouvé ! Bon la concurrence est rude quand on voir opticoupe...

    Merci encore pour le coup de main !

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Ingénieur avant-vente
    Inscrit en
    Mai 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur avant-vente
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2014
    Messages : 5
    Par défaut
    Bon j'étais enthousiaste ce matin mais après avoir essayé de mettre en œuvre c'est pas la même

    Enfaite je ne comprend pas cette ligne et donc je n'arrive pas à l'intégrer:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dim result = From el As Barre In Me Select el Order By el.Longueur Descending
    Bon ça c'est bon
    From el As Barre
    ça aussi c'est l'objet c'est clair
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    In Me Select el Order By
    là j'ai décroché :-D Je suis dans un document "Module" dans mon cas, je ne vois pas comment intégrer cette ligne chez moi.

    J'ai essayé plein de truc à la place de "Me" (je vais pas les énonces pas envie d'être ridicule ) et j'ai soit des erreurs soit rien.

    Je suis quand même étonné qu'on puisse pas utilisé méthode "Sort" de la classe List(of).

    Bon les questions sont peut être stupides mais je suis qu'un jeune débutant plein d'espoir et d'envie de programmation

    Merci encore d'avance en tout cas !

  6. #6
    Membre émérite
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Décembre 2012
    Messages
    337
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2012
    Messages : 337
    Par défaut
    Bonjour,

    Ce n'est pas dans un module qu'il faut mettre cette fonction mais dans la définition de la classe Nommenclature

    Si vous reprenez le code que je vous ai fourni plus haut, Nomenclature est une classe qui hérite de List(Of T) et de ce fait, on peut surcharger la fonction .Sort().

    Le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Dim result = From el As Barre In Me Select el Order By el.Longueur Descending
    est une requête Linq To Object

    "Me" représente la classe nommenclature

    "Select el" veut dire sélectionne l'objet Barre (les valeurs retournées dans result serront des barres)

    "Order By el.Longueur Descending" = range les barres par longueur décroissantes.

    Si vous voulez plutôt écrire une fonction simple à laquelle vous passez en paramètre une List(Of Barre) ça donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Public Function SortBarreList(ByVal _List As List(Of Barre) As List(Of Barre)
    Dim Result = From el As Barre In _List Select el Order By el.Longueur Descending
     
    Return CType(Result.ToList(), List(Of Barre))

Discussions similaires

  1. Passer d'une int list a une string list
    Par slayer___ dans le forum Caml
    Réponses: 1
    Dernier message: 08/05/2008, 16h46
  2. Regrouper une liste en liste de listes
    Par West01 dans le forum Prolog
    Réponses: 12
    Dernier message: 14/03/2008, 14h07
  3. la fonction sort pour trier une liste
    Par memo07 dans le forum C++Builder
    Réponses: 3
    Dernier message: 25/11/2007, 16h58
  4. Comment dédoubler une liste ou un string ?
    Par Guigui_ dans le forum Général Python
    Réponses: 7
    Dernier message: 09/03/2007, 08h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo