Utilisation de linq au lieu de Dictionary

Résolu
cs_JMO Messages postés 1854 Date d'inscription jeudi 23 mai 2002 Statut Membre Dernière intervention 24 juin 2018 - 7 déc. 2016 à 11:57
Whismeril Messages postés 19024 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 18 avril 2024 - 8 déc. 2016 à 07:17
Bonjour le Forum,
J'extrais le contenu d'une page Web.
        Dim Web As WebBrowser = New WebBrowser
        Web.Navigate(address1)
        While Not Web.ReadyState = WebBrowserReadyState.Complete
            Application.DoEvents()
        End While

        Dim text As String = Web.DocumentText.ToString()

La variable "text" contient entre autre
addIndex('CRZ : TOTO','CRZ-C2O','192....');	
addIndex('CRZ : TOTO','CRZ-OXA','192....');	
addIndex('ABC : TITI','ABC-001','192....');	
addIndex('ABC : TITI','ABC-002','192....');
addIndex('XXX : TATA','XXX-001','192....');	
addIndex('XXX : TATA','XXX-002','192....');


Je récupère (Distinct) le trigramme et le nom du client (ex: CRZ et TOTO)
        Dim dicoCustomer As New Dictionary(Of String, String)
        Dim patern As String = "addIndex\('(?<trigramme>[A-Z0-9-]{3}) : (?<client>[^']+)"

        For Each m As Match In Regex.Matches(text, patern)
            If (m.Success) Then
                If Not dicoCustomer.ContainsKey(m.Groups("trigramme").Value) Then
                    dicoCustomer.Add(m.Groups("trigramme").Value, m.Groups("client").Value)
                End If
            End If
        Next

        Me.ComboBox1.Items.Add("Sélection du contrat")
        Me.ComboBox1.Items.Add("Tous les contrats")

        Dim sorteddicoCustomer = (From entry In dicoCustomer Order By entry.Key Ascending).ToDictionary(Function(pair) pair.Key, Function(pair) pair.Value)
        For Each pair As KeyValuePair(Of String, String) In sorteddicoCustomer
            Me.ComboBox1.Items.Add(pair.Key & " - " & pair.Value)
        Next

Ma question :
Suite à des exemples, avec Linq, de vb95 et de Whismeril (clin d'oeil pour Diego !!!)
        Dim occurencesPhrase = (
From c In "Je suis même pas ici, je suis où pourquoi ?".Normalize(NormalizationForm.FormD).ToLower()
Where Char.IsLetter(c)
Group c By c Into leGroup = Group
Select New With {Key .Lettre = c.ToString(), Key .Occurence = leGroup.Count()})
Est-il possible d'utiliser linq au lieu d'un dictionnaire ???

Genre:
Dim myindex = (
    From c In text 
   Where ....
   Select New With {Key .trigramme = ?????, Key .customer = ????}) 

jean-marc

4 réponses

vb95 Messages postés 3472 Date d'inscription samedi 11 janvier 2014 Statut Contributeur Dernière intervention 13 avril 2024 169
7 déc. 2016 à 18:28
Bonsoir cs_JMO
Il est vrai que j'ai utilisé Linq dans les 3 projets autour du Scrabble que j'ai mis sur le site !
Il faut dire que ce sont des exemples de notre ami Whismeril qui m'ont induit à l'utiliser .
Dans une collection au lieu de parcourir tous les éléments par une boucle pour trouver celui qui correspondait à une condition bien précise j'ai utilisé Linq qui me permettait de produire un code beaucoup plus court et tout aussi compréhensible !
Je n'ai jamais encore utilisé un Dictionnairy et j'en suis aux balbutiements côté Linq !
Alors pour t'aider cela va être chaud pour moi !
Je pense que Whismeril est bien plus capable que moi sur ce point !
Salutations à toi
0
cs_JMO Messages postés 1854 Date d'inscription jeudi 23 mai 2002 Statut Membre Dernière intervention 24 juin 2018 27
7 déc. 2016 à 18:34
Bonsoir vb95,

Whismeril m'a déjà aidé dans différents projets avec Linq.
Effectivement, il est fortiche !!! Il code en C+, puis le traduit en .Net.
Moi-aussi, j'en suis aux balbutiements.

Bonne soirée,
jean-marc
0
Whismeril Messages postés 19024 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 18 avril 2024 656
Modifié par Whismeril le 7/12/2016 à 18:42
Bonsoir

pour être sûr d'avoir bien compris,
tu vas lire du texte, tu récupères des couples Trigramme/Client, si le trigramme n'existe pas (en tant que clé) dans un dictionnaire tu ajoutes le couple.

Quand j'étais petit, la mer Morte n'était que malade.
George Burns
0
cs_JMO Messages postés 1854 Date d'inscription jeudi 23 mai 2002 Statut Membre Dernière intervention 24 juin 2018 27
7 déc. 2016 à 18:49
Bonsoir Whismeril,

Oui, c'est cela.
Je souhaiterai ne plus utiliser de dico et le faire par Linq.
Je n'ai pas besoin de savoir combien de "trigramme - client" a été trouvé.

jean-marc
0
Whismeril Messages postés 19024 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 18 avril 2024 656
Modifié par Whismeril le 7/12/2016 à 19:19
Ok, mais si tu as plusieurs trigrammes identiques quel client tu gardes, le 1er, le second, le dernier?
Quand j'étais petit, la mer Morte n'était que malade.
George Burns
0
cs_JMO Messages postés 1854 Date d'inscription jeudi 23 mai 2002 Statut Membre Dernière intervention 24 juin 2018 27
7 déc. 2016 à 19:27
addIndex('CRZ : TOTO','CRZ-C2O','192....');	
addIndex('CRZ : TOTO','CRZ-OXA','192....');
addIndex('ABC : TITI','ABC-001','192....');
addIndex('ABC : TITI','ABC-002','192....');
addIndex('XXX : TATA','XXX-001','192....');
addIndex('XXX : TATA','XXX-002','192....');


Dans cette vue du fichier, "CRZ-C2O" et "CRZ-OXA" représentent deux serveurs.

Au premier (.First) de "CRZ-TOTO", après si trouvé on l'ignore.
0
Whismeril Messages postés 19024 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 18 avril 2024 656
7 déc. 2016 à 19:53
Et les autres infos de la ligne,tu les ignores?
0
cs_JMO Messages postés 1854 Date d'inscription jeudi 23 mai 2002 Statut Membre Dernière intervention 24 juin 2018 27 > Whismeril Messages postés 19024 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 18 avril 2024
7 déc. 2016 à 20:01
Si dans
addIndex('CRZ : TOTO','CRZ-C2O','192....');	
on peut extraire

CRZ, TOTO et CRZ-C2O
CRZ, TOTO et CRZ-OXA
ça serait le top, car j'aurai le trigramme, le nom du client et tous les noms de serveurs par client.
Mais dur la RegEx !!! En tout cas pour moi.

Merci Whismeril de ton temps passé.
0
Whismeril Messages postés 19024 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 18 avril 2024 656
7 déc. 2016 à 20:06
Ok, je jette l'IP donc
0
cs_JMO Messages postés 1854 Date d'inscription jeudi 23 mai 2002 Statut Membre Dernière intervention 24 juin 2018 27 > Whismeril Messages postés 19024 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 18 avril 2024
7 déc. 2016 à 20:28
Oui, après sélection d'un trigramme dans la combo, je fais
    Sub DownLoad(trigramme As String)
Dim client As New WebClient()
If trigramme = "Tous les contrats" Then
'ici boucle sur ListOf, actuellement sur dictionnaire
Else
client.DownloadFile(URL_FileName & trigramme, pathroot & "Client-" & trigramme & ".xlsx")
End If
client.Dispose()
MessageBox.Show("DownLoad OK")
End Sub


L'extraction des trigrammes/client de la page Web me permet d'avoir une liste à jour pour pouvoir l'afficher dans le combo, puis au choix de faire un download du/des fichiers souhaités.
0
Whismeril Messages postés 19024 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 18 avril 2024 656
7 déc. 2016 à 21:41
        Dim texte As String = "addIndex('CRZ : TOTO','CRZ-C2O','192....'" & Environment.NewLine & _
                                "addIndex('CRZ : TaTO','CRZ-OXA','192....'" & Environment.NewLine & _
                                "addIndex('ABC : TITI','ABC-001','192....'" & Environment.NewLine & _
                                "addIndex('ABC : TeTI','ABC-002','192....'" & Environment.NewLine & _
                                "addIndex('XXX : TATA','XXX-001','192....'" & Environment.NewLine & _
                                "addIndex('XXX : TiTA','XXX-002','192....'"

        Dim pattern As String = "addIndex\('(?<trigramme>[A-Z0-9-]{3}) : (?<client>[^']+)','(?<serveur>[^']+)" 'en fait le pattern n'est pas si compliqué que ça, il y a le séparateur ',' et à nouveau tout sauf ' plusieurs fois

        Dim toutesLesLignes As IEnumerable(Of LaClasse2JMO) = (
            From m In Regex.Matches(texte, pattern).Cast(Of Match)()'MatchCollection n'est pas "Linquable" directement, d'ou le Cast<Match>
            Where m.Success
            Select New LaClasse2JMO(m))


        Dim resultat As List(Of LaClasse2JMO) = (
               From l In toutesLesLignes
               Group l By l.Trigramme Into leGroup = Group
                Select New LaClasse2JMO With {.Trigramme = leGroup.First().Trigramme, .Client = leGroup.First().Client, .Serveur = leGroup.First().Serveur}).ToList()'là on groupe et on prend le premier

        ComboBox1.DataSource = resultat


Imports System.Text.RegularExpressions

Public Class LaClasse2JMO
    Public Sub New()
    End Sub

    Public Sub New(ByVal M As Match)
        Trigramme = M.Groups("trigramme").Value
        Client = M.Groups("client").Value
        Serveur = M.Groups("serveur").Value
    End Sub

    Public Property Trigramme() As String

    Public Property Client() As String

    Public Property Serveur() As String

    Public Overrides Function ToString() As String
        Return Trigramme & " - " & Client & " => " & Serveur
    End Function
End Class

0
cs_JMO Messages postés 1854 Date d'inscription jeudi 23 mai 2002 Statut Membre Dernière intervention 24 juin 2018 27
7 déc. 2016 à 22:26
Merci Whismeril,

Je ne vais pas utiliser le datasource pour charger la combobox car je veux simplement y afficher le trigramme et le client.
Je suis entrain de regarder pour lister tous les serveurs d'un trigramme/client.

Encore un grand merci pour ta gentillesse et ton temps passé à m'initier au Linq.

Bonne soirée,
jean-marc
0
Whismeril Messages postés 19024 Date d'inscription mardi 11 mars 2003 Statut Contributeur Dernière intervention 18 avril 2024 656
8 déc. 2016 à 07:17
Je suis entrain de regarder pour lister tous les serveurs d'un trigramme/client.


Tu peux ajouter une propriété qui concatène le trigramme et le client.
Tu fais un groupement sur cette propriété et tu auras tous les serveurs d'un trigramme/client
0
Rejoignez-nous