Chercher dans un array avec uniquement le début du nom [VB]

Jayme65 Messages postés 66 Date d'inscription lundi 23 avril 2007 Statut Membre Dernière intervention 26 mars 2019 - 29 nov. 2011 à 17:14
 Utilisateur anonyme - 1 déc. 2011 à 16:58
Bonjour,

J'ai une liste d'objet

Public romIndex As New List(Of Games)


Voici classe objet 'game' dans laquelle j'ai intégré une fonction de comparaison basée sur 'descript'.

Public Class Games
    Public Shared ReadOnly DescriptComparer As New DescriptComparerClass
    Public rom As String
    Public descript As String
    Public genre As String
    Sub New()
    End Sub
    Public Class DescriptComparerClass
        Implements IComparer(Of Games)
        Public Function Compare(ByVal x As Games, ByVal y As Games) As Integer Implements System.Collections.Generic.IComparer(Of Games).Compare
            Return String.Compare(x.descript, y.descript, True)
        End Function
    End Class
End Class


Ce qui me permet de faire du tri et BinarySearch basé sur 'descript' dans la liste

romIndex.Sort
Dim ng As New Games
ng.descript = "test"
Dim ndx As Int32 = romIndex.BinarySearch(0, romIndex.Count, ng, Games.DescriptComparer)
If ndx >= 0 Then
   Debug.Print ("Trouvé")
End If




Alors, voila ma question:
===============

Comment pourrais-je faire une recherche dans la liste en partant uniquement des lettres du début du string. Donc pour reprendre l'exemple, trouver dans la liste le premier élément qui commencerait par "Te" (et qu'il me trouve "Test").

Pour l'instant j'ai simplement une boucle, mais je voudrais quelque chose de plus abouti car cela concerne des dizaines de milliers d'éléments et je sais qu'il doit y avoir plus performant que ma boucle

For Each ri As Games In romIndex
 If ri.descript.ToUpper.StartsWith(texteàtrouver) Then
  ...
  ...
  Exit For
 End If
Next


Que puis je utiliser (et comment) qui ait la même "rapidité" qu'un BinarySearch (sur le string complet) avec uniquement le début d'un string?



J'espère que j'ai pu me faire comprendre ;-) et je vous remercie d'avance de l'aide que vous voudrez bien m'apporter

7 réponses

Utilisateur anonyme
29 nov. 2011 à 18:21
Bonsoir,

Je ne sais pas si ce sera plus rapide mais tu peux tenter d'utiliser les 'predicate'
Un petit exemple simpliste à tester avec une listbox et un textbox pour bien comprendre le fonctionnement :
Public Class Form1
    Dim mots() As String = {"banane", "bateau", "bijou", "batman"}

    Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
        ListBox1.Items.Clear()
        ListBox1.Items.AddRange(Array.FindAll(mots, AddressOf Recherche))
    End Sub

    Private Function Recherche(ByVal mot As String) As Boolean
        Return mot.StartsWith(TextBox1.Text)
    End Function
End Class
0
Utilisateur anonyme
29 nov. 2011 à 18:55
Tu peux aussi utiliser Linq (ici je cherche les mots commencant par ba et je trie selon leur longueur :
Dim requete As IEnumerable(Of String) = From mot As String In mots
                                        Where mot.StartsWith("ba") 
                                        Order By mot.Length 
                                        Ascending
For Each mot As String In requete
    Debug.Print(mot)
Next
0
Jayme65 Messages postés 66 Date d'inscription lundi 23 avril 2007 Statut Membre Dernière intervention 26 mars 2019 2
1 déc. 2011 à 14:33
banana32,
Merci pour ta réponse, qui me semble être de fait la direction que je devrais choisir!
Si je peux encore te demander quelque chose:
Comment avec l'utilisation de LINQ rechercher le premier éléments qui commence par les quelques lettres du début...et avoir son index en retour

En clair, si dans ma 'list(of Games)' j'ai des élément dont la propriété '.descript' = "TestA", "TestB", TostA", TostB",
je veux pouvoir, si j'entre "Te", trouver le premier, à savoir "TestA" et avoir son index en retour.

D'avance merci!!!
0
Utilisateur anonyme
1 déc. 2011 à 16:32
Si dans ta classe, tu as prévu de joindre un index :
Public Class Games
    Public Shared ReadOnly DescriptComparer As New DescriptComparerClass
    Public rom As String
    Public descript As String
    Public genre As String
    '........
    Public Index as integer

    'profite du constructeur pour renseigner l'index par exemple
    sub new(nIndex as integer)
         Index = nIndex
         '...........


Tu pourras le récupérer ensuite :

Dim requete As IEnumerable(Of Games) = From game As Games In romIndex
                                        Where game.descript.StartsWith("Te") 
for each game as Games in requete
    messagebox.show(game.index)
next
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Utilisateur anonyme
1 déc. 2011 à 16:35
oups
messagebox.show(game.index.tostring)
0
Utilisateur anonyme
1 déc. 2011 à 16:38
Ou bien, tu peux te passer d'un index aussi en faisant :
romIndex.IndexOf(game)
0
Utilisateur anonyme
1 déc. 2011 à 16:58
Pardon j'ai répondu sans avoir compris que tu ne voulais garder que le premier. Fais un Exit For pour sortir de la boucle de manière à ne lire que le premier élément.

J'ai remarqué que tu tri ta liste :
romIndex.Sort

Donc, si tu ne met pas un index dans ta classe, ceux-ci vont bouger lors du tri. Mais tout dépend de quelle manière tu fais ton tri (jette un coup d'oeil sur les différentes surcharges de la méthode Sort pour un tri efficace).

Bonne soirée.
0