none
Créer une liste d'objets...puis la trier sur 1 des objets en ne prenant pas en compte la différence majuscule/minuscule RRS feed

  • Question

  • Bonjour,

    Je devais créer un tableau à 2 dimensions.
    Je me suis dit que je pouvais le faire en créant une classe, et en faisant un: List (Of ma classe)

     

    Public Class Displayed
      Public rom As String
      Public descript As String
    End Class
    
    Sub feedArray()
      Dim displayArray As New List(Of Displayed)
      displayArray.Add(New Displayed() With {.descript = "AAA", .rom = "zzz"})
      displayArray.Add(New Displayed() With {.descript = "bbb", .rom = "YYY"})
      displayArray.Add(New Displayed() With {.descript = "CCC", .rom = "xxx"})
    End Sub
    

    Première chose: était ce une bonne façon de procéder? Y a t-il plus 'simple' que de créer une classe objet
    Y a t-il une autre façon de créer un array/list multi-dimensionnel, avec une taille non définie dès le départ?

    Et surtout: comment dois-je faire maintenant pour le trier, alphabétiquement, en choisissant  la clé qui va servir au tri ('descript', ou 'rom')...et pour terminer, en ne prenant pas en compte la différence entre majuscule et minuscule ("case insensitive" dans..ActionScript)

    Un grand merci pour votre aide!!!

    mercredi 30 mars 2011 16:53

Réponses

  • Voila un petit exemple. Ma mémoire m'a joué un tour. ISortable n'existe pas, c'est IComparable. Quand une classe implémente la méthode IComparable.CompareTo, ses instances peuvent-être triées (notament par les listes).

    Je ne sais pas s'il existe une technique plus propre que la propriété partagée pour conditionner le tri.

    J'ai également mis un exemple de déclaration de dictionnaire insensible à la casse (issu de la documentation)

    Public Class Displayed
      Implements IComparable(Of Displayed)
    
      Public Enum SortOptions
        descript
        rom
      End Enum
    
      Public Shared SortKey As SortOptions = SortOptions.descript
      Public rom As String
      Public descript As String
    
      Public Function CompareTo(ByVal other As Displayed) As Integer Implements System.IComparable(Of Displayed).CompareTo
        Select Case Displayed.SortKey
          Case SortOptions.descript
            Return String.Compare(Me.descript, other.descript, True)
          Case SortOptions.rom
            Return String.Compare(Me.rom, other.rom, True)
        End Select
      End Function
    
      Private Sub Test()
        'Pour l'exemple de dictionnaire avec clés non sensibles à la casse
        Dim dic As New Dictionary(Of String, Displayed)(StringComparer.CurrentCultureIgnoreCase)
      End Sub
    
    

     

     

    jeudi 31 mars 2011 05:33

Toutes les réponses

  • Bonjour,

    Et en programmation objet ? Un envoyant dans une listBox si le nombre est inférieur  65.000, tu as ton tableau en formatant pour que chaque donné possède la même largeur (font couRier New).

    Exemple

    listbox1 data1 data2 data3 data4
    En CouRier New formaté pour qu'elles aient toute la même largeur
    En data1 et data2 (clef, nom), en minuscules pour le tri (listbox ... sorted = true), et en data3 et data4 comme d'origine su tu as besoin de recomposer l'origine.
    Ensuite pour trier, composer, avec une listbox2 tu prends la listbox1 les éléemtns désirés...
    

    Pour déclarer une variable tableau sans dimension d'origine, il y a au moins:

    dim x() as letype
    quand tu connais le nombre
    ReDime(lenombre)
    

    Cordialement.



    Joseph Attila PUSZTAY
    EhJoe       Logiciels       Romans       Ecrire
    mercredi 30 mars 2011 17:35
  • EhJoe,

    Merci pour ta réponse..mais je ne suis pas certain qu'elle s'adresse à moi!? ;-)
    Je ne parle pas de listbox, je suis dans une liste d'objets multidimensionnel que je voudrais trier par ordre alphabétique en ignorant la distinction minuscule/majuscule (car, je ne sais pas si c'est la cas avec VB..mais dans un autre language de programmation, les mots avec majuscule apparaissent avant ceux en minuscule)



    • Modifié jmdeb mercredi 30 mars 2011 19:06
    mercredi 30 mars 2011 18:12
  • Merci EhJoe!

    Pour reprendre mon premier exemple

    Public Class Displayed
     Public rom As String
     Public descript As String
    End Class
    
    Sub feedArray()
     Dim displayArray As New List(Of Displayed)
     displayArray.Add(New Displayed() With {.descript = "AAA", .rom = "zzz"})
     displayArray.Add(New Displayed() With {.descript = "bbb", .rom = "YYY"})
     displayArray.Add(New Displayed() With {.descript = "CCC", .rom = "xxx"})
    End Sub

    Je voudrais quelque chose du style (imaginaire lol)
    displayArray.Sort("descript", Array.CASEINSENSITIVE)

    De façon a trier displayArray par sa clé 'descript' en s'assurant que l'orde est bien AAA, bbb, CCC...et non pas AAA, CCC, bbb, comme c'est la cas en ActionScript (et oui, en conservant leur casse initiale)


    mercredi 30 mars 2011 19:13
  • Bonsoir,

    Je me suis rarement intéressé à cela, mais toute classe peut être rendu "triable" (??)

    Tu ajoutes "Implements ISortable" (de mémoire) sous la déclaration Public Class Displayed et VS va ajouter toutes les méthodes à complèter.

    Dans ton cas, c'est un peu particulier car ces méthodes devront renvoyer des valeurs (-1, 0, ou 1) en fonction d'un paramètre partagé par toutes les instances de ta classe (par exemple SortKey de type chaîne dans lequel tu places "descript" ou "rom".

    Public Shared Property SortKey AS String

    Ces méthodes comparent deux éléments, donc sont très simples à implémenter.

    Pour la comparaisons non sensible à la casse, utilise String.Compare(s1, s2, True) (le True est pour le paramètre IgnoreCase).

    Sinon, pour toutes les collections, dictionnaires et autres, il y a un constructeur (New) qui permet de passer en paramètre un "type" de tri. Je regarderai pour un exemple si tu le souhaites.

    Fred

     

    mercredi 30 mars 2011 19:17
  • Bonsoir,

    Tiens, voici un tri par les objets "qui s'adresse à toi", passant des tris en aveugle par variable de 1979 aux trix par objets de 2011, c'est juste un zest plus long, par contre ça permet de voir ce qui se passe et de corriger les inévitables erreurs (sauf pour ceux qui ne posent pas de question) : Car en fait, quand il y a une erreur, ce qui est inévitable dans une programmation importante, il faut ensuite afficher pour comprendre, alors, tant qu'à faire, afficher avant n'est pas plus mauvais :o)

    Il faut juste prendre une form1, lui coller 3 list et coller le code !

    Option Explicit On
    Public Class Form1
     
     Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
     Dim i As Integer
     Dim j As Long
     ' chargement pour l'exemple = list1
     ListBox1.Font = New Font("Courier New", 12, FontStyle.Regular)
     ListBox1.Items.Clear()
     ListBox1.Items.Add("Un   05")
     ListBox1.Items.Add("deux  06")
     ListBox1.Items.Add("TROIS 07")
     ListBox1.Items.Add("Quatre 04")
     ListBox1.Items.Add("cinq  08")
     ListBox1.Items.Add("Six  03")
     ListBox1.Items.Add("SETP  09")
     ListBox1.Items.Add("Huit  02")
     ListBox1.Items.Add("neuf  01")
     ListBox1.Items.Add("Dix  11")
     '
     ' classement sur muniscules
     ListBox2.Font = New Font("Courier New", 12, FontStyle.Regular)
     ListBox2.Items.Clear()
     ListBox2.Sorted = True
     For i = 0 To ListBox1.Items.Count - 1
      ListBox2.Items.Add(LCase(ListBox1.Items(i)))
     Next
     '
     ' tri sur inversion des datas de chaque ligne
     ListBox3.Font = New Font("Courier New", 12, FontStyle.Regular)
     ListBox3.Sorted = True
     ListBox3.Items.Clear()
     For i = 0 To ListBox2.Items.Count - 1
      ListBox3.Items.Add(Mid(ListBox2.Items(i), 8, 2) & " " & Mid(ListBox2.Items(i), 1, 7))
     Next
     End Sub
     
     Sub Form1_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
     ' variable tableau en index indéfini au départ
     Dim n() As String
     ReDim n(ListBox3.Items.Count)
     For i = 0 To ListBox3.Items.Count - 1
      n(i + 1) = ListBox3.Items(i)
     Next i
     MsgBox(n(3))
     End Sub
    End Class 
    
    

    Ce qui donne respectivement dans les trois listes :

    -----------1
    Un    05
    deux  06
    TROIS 07
    Quatre 04
    cinq   08
    Six   03
    SETP  09
    Huit   02
    neuf  01
    Dix   11
    ----------2
    cinq   08
    deux  06
    dix   11
    huit   02
    neuf  01
    quatre 04
    setp  09
    six   03
    trois  07
    un    05
    ---------3
    01 neuf  
    02 huit  
    03 six  
    04 quatre 
    05 un   
    06 deux  
    07 trois 
    08 cinq  
    09 setp  
    11 dix  
    

    Cordialement.

     



    Joseph Attila PUSZTAY
    EhJoe       Logiciels       Romans       Ecrire
    • Proposé comme réponse EhJoe mercredi 30 mars 2011 20:02
    mercredi 30 mars 2011 20:00
  • Je regarderai pour un exemple si tu le souhaites.
    Bien volontier Fred!!! Merci!
    jeudi 31 mars 2011 00:37
  • Voila un petit exemple. Ma mémoire m'a joué un tour. ISortable n'existe pas, c'est IComparable. Quand une classe implémente la méthode IComparable.CompareTo, ses instances peuvent-être triées (notament par les listes).

    Je ne sais pas s'il existe une technique plus propre que la propriété partagée pour conditionner le tri.

    J'ai également mis un exemple de déclaration de dictionnaire insensible à la casse (issu de la documentation)

    Public Class Displayed
      Implements IComparable(Of Displayed)
    
      Public Enum SortOptions
        descript
        rom
      End Enum
    
      Public Shared SortKey As SortOptions = SortOptions.descript
      Public rom As String
      Public descript As String
    
      Public Function CompareTo(ByVal other As Displayed) As Integer Implements System.IComparable(Of Displayed).CompareTo
        Select Case Displayed.SortKey
          Case SortOptions.descript
            Return String.Compare(Me.descript, other.descript, True)
          Case SortOptions.rom
            Return String.Compare(Me.rom, other.rom, True)
        End Select
      End Function
    
      Private Sub Test()
        'Pour l'exemple de dictionnaire avec clés non sensibles à la casse
        Dim dic As New Dictionary(Of String, Displayed)(StringComparer.CurrentCultureIgnoreCase)
      End Sub
    
    

     

     

    jeudi 31 mars 2011 05:33
  • > Je ne sais pas s'il existe une technique plus propre que la propriété
    > partagée pour conditionner le tri.
     
    Et si, il y a plus propre, c'est de créer des classes qui implémentent
    IComparer(T)
     
     --
    Fred
    foleide@free.fr
     
    jeudi 31 mars 2011 05:53
  • Bonjour JMDeb,

    Désolé, comme tu veux faire, mettre en tableau puis trier, je l'aurais fait autrement, je ne sais pas faire selon ta méthode, notamment le tri ;o)

    Pour ma part depuis qu'il y a des objets je les utilise, ils font très bien ce que tu veux faire joints aux fonctions de manipulations de chaînes, mais c'est toi qui vois :o)

    Tu as aussi une autre fonctionnalité que j'utilisais en vb6 :

    Private Type nom_du_goupe_type
     nom_var_1 As ...
     nom_var_2 As ...
    End Type
    Dim nom_variable_du_type As nom_du_groupe_type
    
    

    Bref, bon développement, et encore navré, cordialement.

     



    Joseph Attila PUSZTAY
    EhJoe       Logiciels       Romans       Ecrire
    jeudi 31 mars 2011 07:32
  • Désolé, comme tu veux faire, mettre en tableau puis trier, je l'aurais fait autrement, je ne sais pas faire selon ta méthode, notamment le tri ;o)

    Pour ma part depuis qu'il y a des objets je les utilise, ils font très bien ce que tu veux faire joints aux fonctions de manipulations de chaînes, mais c'est toi qui vois :o)

    Bref, bon développement, et encore navré, cordialement.

    Au contraire, un grand merci pour ton aide et ta collaboration!
    En fait, je cherchais une façon 'simple' de trier une liste de paire, sur 1 des deux membres (je ne suis pas dans une listBox, ce tri se fait en 'interne'). Peut être ai-je été voir trop loin, en faisant une liste d'objets générique?!
    Mais dans ce cas, comment faire simplement cette liste, constituée de paire..et de la trié sur 1 de ses membres ?

    Merci d'avoir pris de ton temps pour moi, EhJoe!!

    jeudi 31 mars 2011 11:20
  • Foleide._

    Grand merci pour ton aide précieuse et bien documentée.
    Grâce à ton aide, j'ai pu ne serait-ce que comprendre la "mécanique" qui se cache derrière cela.
    J'ai pu aiguiller ma recherche sur ce sujet (j'ai d'ailleurs trouvé ce http://support.microsoft.com/kb/321292/fr très utile)
    Et donc, pour l'instant, j'en suis là..et ca marche (sans la notion de casse, pour l'instant):

    Public Class Displayed
     Implements IComparable
     Public rom As String
     Public descript As String
     Function CompareTo(ByVal obj As Object) As Integer Implements IComparable.CompareTo
      Dim c As Displayed = CType(obj, Displayed)
      Return String.Compare(Me.descript, c.descript)
     End Function
    End Class
    
    Sub feedArray()
     Dim displayArray As New List(Of Displayed)
     displayArray.Add(New Displayed() With {.descript = "AAA", .rom = "zzz"})
     displayArray.Add(New Displayed() With {.descript = "bbb", .rom = "YYY"})
     displayArray.Add(New Displayed() With {.descript = "CCC", .rom = "xxx"})
    End Sub
    
    displayArray.Sort()

    Pour ce qui est de ta derniere réflexion:
    Et si, il y a plus propre, c'est de créer des classes qui implémentent IComparer(T)
    ...je dois encore comprendre cela et chercher à l'implémenter ;-)

     

    Merci, merci, merci :)


    jeudi 31 mars 2011 11:25
  • Bonjour,

    J'ai proposé un article, avec un exemple, au sujet de ta problématique ici :
    http://social.msdn.microsoft.com/Forums/fr-FR/vbasicfr/thread/6f0fd1a8-be68-4cd2-9c54-fb63537bf596

     

    lundi 4 avril 2011 04:38
  • Bonjour Foleide._

    Je reviens vers toi, pour quelque chose de très similaire (à mon avis!)

     

    Public gameDB As New Dictionary(Of String, Games)
    
    gameDB.Add("nom_01", New Games() With {.rom = "qqchose1", .clone = "qqchose2", .descript = "qqchose3", .genre = "qqchose4"})
    
    Public Class Games
     Public rom As String
     Public clone As String
     Public descript As String
     Public genre As String
    End Class
    

     

    Comme tu le vois, j'ai créé un dictionnaire qui va "pairer" un nom avec ses 4 propriétés (je ne sais pas si la terminologie est exacte ;-))
    Il y a +/- 9000 noms et donc autant de propriétés
    Or, il se fait qu'à un moment, je dois rechercher si une des propriétés contient une valeur spécifique (est ce qu'il existe une valeur "qqchose3" dans la propriété .descript d'une de mes 9000 entrés du dictionnaire!)...et me retourner le nom de l'entrée dictionnaire  (et cette opération doit être effectuée plusieurs fois dans mon programme)

    Comme un débutant (que je suis ;-)) je fais, en attendant mieux, une boucle dans les 9000 entrées, pour chacune de mes recherches, jusqu'à ce que je tombe sur la valeur (ah oui, important: cette valeur est unique et ne peut se trouver que dans 1 seule entrée)

    Les petites bases que j'ai, me font penser qu'il serait plus efficace de faire un tri sur '.descript', puis un binarySearch...

    J'ai l'impression que la mécanique doit être fort semblable à ce dont nous avons déjà parlé, n'est pas? Peux tu m'aider, à nouveau, sur ce "problème"?

    Merci!!!




    mercredi 6 avril 2011 15:35
  • > Bonjour Foleide._
     
    Bonjour,
     
    Ton problème est typiquement un problème de base de données. Tu as des
    lignes auxquelles tu dois accéder en utilisant divers indexes.
    Dans le cas que tu mentionnes, je construirais plusieurs dictionnaires
    au chargement selon les clés dont tu as besoin par la suite.
    Dim game as New Games With {....}
    gameByName.Add("nom_01", game)
    gameByDescript.Add(game.descript, game)
    etc ...
     
    D'ailleurs, pourquoi ne pas créer une propriété "nom" dans la classe Games ?
     
    Mais pour en revenir aux base de données, as-tu songé à utiliser un vrai
    système de gestion de données ? Tel que SQLCE, qui se contente de 3 ou 4
    dll et est relativement puissant pour sa taille.
    Tu pourrais alors créer une table Games, poser autant d'indexes dessus
    que nécessaires, et profiter d'algorithmes perfectionnés de requêtage.
     --
    Fred
    foleide@free.fr
     
    jeudi 7 avril 2011 03:04
  • Bonjour Foleide._

    Merci pour ta réponse! Bien que j'imagine que tu aies raison concernant SQLCE...je ne vais pas y recourir cette fois, car c'est la seule opération sur la "base" dont j'ai encore besoin. Je vais donc suivre ta première proposition.

    Juste une note: il existe bel et bien une propriété "nom" dans la classe Game! J'ai mal écrit mon exemple, qui en effet est plûtot:

    gameDB.Add("nom_01", New Games() With {.rom = "nom_01", .clone = "qqchose2", .descript = "qqchose3", .genre = "qqchose4"})

    Qu'est ce que ça va changer? A quoi penses tu quand tu me dit cela?

    Et si j'utilise la technique que tu préconise, le fait de faire une recherche (if ...contains, j'imagine?!) dans gameByDescript, me permettra donc de pouvoir trouver la valeur du gameByName voisin?! Comment stp?

    J'espère que tu auras un peu de temps à me consacrer? Mais quoi qu'il en soit, je te remercie pour ton aide!!

     

    jeudi 7 avril 2011 16:23
  •  
    > Bonjour Foleide._
     
    Bonjour
     
    > Juste une note: il existe bel et bien une propriété "nom" dans la classe
    > Game! J'ai mal écrit mon exemple, qui en effet est plûtot:
    > Qu'est ce que ça va changer? A quoi penses tu quand tu me dit cela?
     
    À rien de particulier, c'est que j'aurais écrit :
    gameByName.Add(game.rom, game)
     
    > Et si j'utilise la technique que tu préconise, le fait de faire une
    > recherche (if ...contains, j'imagine?!) dans gameByDescript, me permettra
    > donc de pouvoir trouver la valeur du gameByName voisin?! Comment stp?
     
    J'ai un peu perdu le fil de ce dont tu as besoin !
    Je pense, par rapport à l'ensemble de tes questions, que la classe qui
    correspond le mieux est la classe SortedList(Of TKey, TValue)
    En utilisant le 2ème constructeur qui te permet de passer un
    StringComparer.InvariantCultureIgnoreCase (ou
    StringComparer.CurrentCultureIgnoreCase) pour ta problématique de tri
    sans tenir compte de la casse. Note que la méthode de l'implémentation
    de l'interface IComparer dont nous avions parlé n'est peut-être plus
    utile avec le SortedList, puisque les clés sont "séparées" de l'objet
    lui-même lors de l'ajout à la liste.
     
    Pour répondre à ta question si je l'ai bien comprise :
    Dim g1 as Game = gameByName("nom_01")
    If g1 IsNot Nothing Then
        Dim g2 as Game = gameByDescript(g1.descript)
    End If
     
    Note que le SortedList renvoie Nothing si la clé n'est pas trouvée.
    Egalement gameByName("nom_01") = g va remplacer l'ancienne valeur si
    elle existe ou en créer une nouvelle si elle n'existe pas.
    Et enfin, il ne peut y avoir de doublon dans les clés.
     
    Avec cette méthode tu vas placer des références à tes objets dans deux
    listes (ou plus). Comme il s'agit de références, chaque objet sera
    représenté une seule fois en mémoire.
     
    Attention si tu modifies une des propriétés qui servent de clé. Car la
    clé utilisée lors du stockage, elle, ne sera pas modifiée. Donc tu peux
    obtenir des listes mal triées.
     
    --
    Fred
    foleide@free.fr
     
    vendredi 8 avril 2011 05:16
  • En fait, tu vois, ce que j'espérais, c'est que de la même façon que l'on avait implémenter le 'sort' dans la classe

    Public Class Displayed
     Implements IComparable
     Public rom As String
     Public descript As String
     Function CompareTo(ByVal obj As Object) As Integer Implements IComparable.CompareTo
     Dim c As Displayed = CType(obj, Displayed)
     Return String.Compare(Me.descript, c.descript)
     End Function
    End Class
    
    Sub feedArray()
     Dim displayArray As New List(Of Displayed)
     displayArray.Add(New Displayed() With {.descript = "AAA", .rom = "zzz"})
     displayArray.Add(New Displayed() With {.descript = "bbb", .rom = "YYY"})
     displayArray.Add(New Displayed() With {.descript = "CCC", .rom = "xxx"})
    End Sub
    
    displayArray.Sort()

    On pourrait également implémenter le binarysearch (qui sur les grandes listes réduit drastiquement la recherche),en se servant de ce qui est ici:

    http://www.java2s.com/Code/VB/Data-Structure/ArrayListBinarySearchObjectIComparer.htm

    http://msdn.microsoft.com/en-us/library/4ba2bttb.aspx

    Penses tu que cela soit possible?



    vendredi 8 avril 2011 06:42
  • > En fait, tu vois, ce que j'espérais, c'est que de la même façon que l'on
    > avait implémenter le 'sort' dans la classe
    > On pourrait également implémenter le binarysearch (qui sur les grandes
    > listes réduit drastiquement la recherche),en se servant de ce qui est ici:
     
    Les deux sont liés. Tu ne peux utiliser le BinarySearch que si ton
    tableau est déjà trié selon le même mode de comparaison.
    Dans ton cas, il semble que tu aies besoin de mutiples recherches.
    Cela signifie que tu devras trier ton tableau avant chaque BinarySearch
    et perdre en performance.
    Avec le SortedList, tu prépares, en quelque sorte des indexes adaptés à
    chaque mode de recherche.
    Dans ton cas, les clés sont des chaînes, tu peux utiliser un IComparer
    Standard et ne pas créer de IComparer pour ta classe.
    Il faut tester pour voir.
    L'algorithme de recherche d'un élément dans un SortedList est
    certainement aussi performant que le BinarySearch (si ce n'est pas
    exactement le même d'ailleurs).
     
    Tu peux également garder tes objets dans un tableau que tu tries selon
    une certaine propriété (avais-tu vu ceci :
    ?)
    et utiliser des SortedList pour des indexes complémentaires.
     
    En complément, le BinarySearch est certainement une dichotomie. Je n'ai pas décompilé pour vérifier (Reflector : outil très utile pour comprendre). D'où la nécessité d'avoir un tableau déjà trié. Je n'ai pas connaissance d'algorithme plus rapide dans ce cas. Ce qui me laisse à croire que c'est la même chose pour la recherche d'une clé dans une SortedList.
    --
    Fred
    foleide@free.fr
    • Modifié Foleide. _ vendredi 8 avril 2011 07:08 Complément
    vendredi 8 avril 2011 07:01
  • Merci Fred de me répondre et de m'accorder de ton temps!

    Il faut que je sois prudent dans ce que je vais ajouter...car j'ai peur de commencer à devenir casse pieds ;-)

    1)

    Les deux sont liés. Tu ne peux utiliser le BinarySearch que si ton
    tableau est déjà trié selon le même mode de comparaison.
    Dans ton cas, il semble que tu aies besoin de mutiples recherches.
    Cela signifie que tu devras trier ton tableau avant chaque BinarySearch
    et perdre en performance.

    Non Fred, ce dictionnaire n'est pas trié jusqu'à présent. Il peut donc être trié une seule fois, sur .descript !!

    gameDB.Add(gamerom, New Games() With {.rom = gamerom, .clone = cloneof, .descript = gamename, .genre = gamegenre, .favorite = fav, .userHave = have})
    
    Il me manque une seule chose: c'est qu'une requête puisse être lancée sur .descript, et qu'il me donne .rom (ou gamerom) pour que je puisse situer le nom de l'entrée dictionnaire..c'est tout ce que je voudrais!!

    Tu vois, de la même façon que nous pouvions utiliser un "dictionnaire.Sort()" grâce à ton aide dans ce topic, je voudrais maintenant un truc du style "dictionnaire.BinarySearch(variable)" qui me retourne gamerom ou .rom

    2) Je t'avoue que j'ai envie de rester dans ma structure actuelle car tout le code est basé et fait référence à ma structure de dictionnaire initial !

     

     

    vendredi 8 avril 2011 08:04
  •  
    > Non Fred, ce dictionnaire n'est pas trié jusqu'à présent. Il peut donc être
    > trié une seule fois, sur .descript !!
     
    OK,
     
    > [/code]Il me manque une seule chose: c'est qu'une requête puisse être
    > lancée sur .descript, et qu'il me donne .rom (ou gamerom) pour que je
    > puisse situer le nom de l'entrée dictionnaire..c'est tout ce que je
    > voudrais!!
     
    Dans ce cas, le BinarySearch avec un IComparer sur la propriété descript
    devrait faire l'affaire.
    Tu lui passes un objet game avec seulement la propriété descript
    initialisée. Pour lui, il sera "égal" à celui du tableau qui a la même
    propriété descript (puisque le IComparer ne tiendra pas compte des
    autres propriétés).
    Je n'ai pas pris le temps de tester cela, mais je n'y vois pas de
    problème potentiel.
     > 2) Je t'avoue que j'ai envie de rester dans ma structure actuelle car tout
    > le code est basé et fait référence à ma structure de dictionnaire initial !
     
    Je comprends bien, je te l'ai proposé, car, à priori, cela se fait avec
    une recherche / remplacement (il y a très peu de différence entre le
    Dictionary et le SortedList). Sans avoir examiné dans le détail, je
    pense que le SortedList est plus performant en extraction (les clés sont
    triées) et moins en insertion (les indexes des clés sont recalculés).
    À toi de voir car cela dépend très fortement de ton programme.
     --
    Fred
    foleide@free.fr
     
    vendredi 8 avril 2011 08:19
  • Dans ce cas, le BinarySearch avec un IComparer sur la propriété descript
    devrait faire l'affaire.
    Tu lui passes un objet game avec seulement la propriété descript
    initialisée. Pour lui, il sera "égal" à celui du tableau qui a la même
    propriété descript (puisque le IComparer ne tiendra pas compte des
    autres propriétés).
    Je n'ai pas pris le temps de tester cela, mais je n'y vois pas de
    problème potentiel.

     Merci Fred...j'essaie de comprendre et d'y arriver par moi-même..mais si, d'aventure, tu as la possibilité/envie de m'aider par du code, je t'en serait....très reconnaissant :-)

    vendredi 8 avril 2011 12:54
  • Bonjour jm,

    Voilà un bout de code. À coller dans un projet Console.

    Module Module1
    
      Sub Main()
        'La liste de base (qui sera triée selon les descriptions)
        Dim gameList As New List(Of Game)
        'L'index qui permet une récupération rapide via le nom (Rom)
        Dim romIndex As New SortedList(Of String, Game)(StringComparer.CurrentCultureIgnoreCase)
        Dim g As Game
        For i As Int32 = 1 To 20
          g = New Game With { _
            .Rom = i.ToString, _
            .Descript = Convert.ToString(i, 16).PadLeft(3, "0")}
          gameList.Add(g)
          romIndex(g.Rom) = g
        Next
        'Tri selon les descriptions
        gameList.Sort(Game.DescriptComparer)
        For i As Int32 = 0 To gameList.Count - 1
          Console.WriteLine(gameList(i))
        Next
        Console.WriteLine()
    
        g = New Game
        Console.Write("Saisir une description : ")
        g.Descript = Console.ReadLine
        'Recherche de l'objet ayant la même description
        Dim ndx As Int32 = gameList.BinarySearch(0, gameList.Count, g, Game.DescriptComparer)
        If ndx >= 0 Then
          Console.WriteLine(gameList(ndx))
        End If
        Console.WriteLine("Appuyer sur Entrée pour finir")
        Console.ReadLine()
      End Sub
    
    End Module
    
    Public Class Game
    
      Public Shared ReadOnly DescriptComparer As New DescriptComparerClass
      Public Rom As String = String.Empty
      Public Descript As String = String.Empty
    
      Sub New()
      End Sub
    
      Public Overrides Function ToString() As String
        Return String.Format("rom : {0,5}  descript : {1}", Me.Rom, Me.Descript)
      End Function
    
      Public Class DescriptComparerClass
        Implements IComparer(Of Game)
    
        Public Function Compare(ByVal x As Game, ByVal y As Game) As Integer Implements System.Collections.Generic.IComparer(Of Game).Compare
          Return String.Compare(x.Descript, y.Descript, True)
        End Function
      End Class
    
    End Class
    
    

    Donc le fait de rechercher un objet "incomplet" fonctionne. C'est en quelque sorte un objet filtre.
    Par contre, inutile de rechercher ensuite un autre objet puisque tu l'as déjà sous la main (?).

    Peut-être n'as tu pas bien saisi le fait que tes objets ne sont pas en double en mémoire. Ce sont uniquement leurs références qui sont stockées à la fois dans gameList et dans romIndex (pour faire référence à mon exemple). J'ai tout de même laissé romIndex qui peut être utilisé pour retrouver un objet par sa propriété Rom.
        g = romIndex(rom)

    Est-ce plus clair ?

    Fred

     

    samedi 9 avril 2011 06:00