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

Composants VCL Delphi Discussion :

TList et IndexOf


Sujet :

Composants VCL Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Octobre 2005
    Messages
    180
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 180
    Par défaut TList et IndexOf
    Bonjour,

    Peut on utiliser la propriété indexOf pour retrouver un objet "complex" dans une TList?
    Pour ce faut il implémenter l'opérateur = ou autre? Je en veux bien sur pas me contenter de comparer juste les pointeur des 2 objets!

    D'avance merci

    Ben

  2. #2
    Membre éprouvé
    Avatar de TicTacToe
    Inscrit en
    Septembre 2005
    Messages
    1 940
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 940
    Par défaut
    Oui

    Il faut pour cela créer une fonction de type TListSortCompare

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    procedure Sort(Compare: TListSortCompare);
     
    ensuite
     
    MaListe.Sort( TaFonctionDeComparaison );
    F1 sur TList.Sort et tu auras toutes les infos.

    bon courage !

    :EDIT:
    autant pour moi j'ai été un peu vite.
    Pour le IndexOf, tu peux juste faire un parcours linéaire et rechercher tes données. De toute manière, IndexOf est lui même linaire...
    donc tu peux faire ton propre MonIndexOf comme ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    IIndexTrouve := -1;
    for i := 0 to MaListe.count - 1 do
    with TMonType( MaListe.Objects[ i ] ) do
      begin
      // tester si élément rempli condition
      if ConditionRemplie then
        begin
        IIndexTrouve := i;
        break;
        end;
      end
    Section Delphi
    La mine d'or: La FAQ, les Sources

    Un développement compliqué paraitra simple pour l'utilisateur, frustrant non ?
    Notre revanche ? l'inverse est aussi vrai ;-)

  3. #3
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    1 132
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 132
    Par défaut
    L'objet TList permet de trier des objets à l'aide d'une fonction de comparaison "perso" passée en paramètre.
    Par contre, il me semble que IndexOf() ne le permette pas.

    Pour cela je ne vois que la solution de faire un dérivé de TList dans lequel tu devras écrire ta propre méthode de recherche (comme dans le TStringList par exemple )

  4. #4
    Membre éprouvé
    Avatar de TicTacToe
    Inscrit en
    Septembre 2005
    Messages
    1 940
    Détails du profil
    Informations personnelles :
    Âge : 52

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 940
    Par défaut
    Note, j'ai modifé mon post d'avant
    Section Delphi
    La mine d'or: La FAQ, les Sources

    Un développement compliqué paraitra simple pour l'utilisateur, frustrant non ?
    Notre revanche ? l'inverse est aussi vrai ;-)

  5. #5
    Membre Expert
    Avatar de e-ric
    Homme Profil pro
    Apprenti chat, bienfaiteur de tritons et autres bestioles
    Inscrit en
    Mars 2002
    Messages
    1 568
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Apprenti chat, bienfaiteur de tritons et autres bestioles

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 568
    Par défaut
    Salut

    je comprend mal ta question et je pense que les réponses proposées ne sont pas pertinentes. IndexOf retourne le premier indice de l'objet paramètre si celui-ci se trouve dans la liste. La recherche est basée sur la comparaison des référence d'objets.

    En ce qui concerne la comparaison, et si tu as la main sur le code de tes objets, ajoutes un méthode TTonObjet.CompareAvec(unAutre : TTonObjet) : boolean;

    La comparaison d'objet Obj1=Obj2 est une comparaison de référence pas une comparaison "profonde" basée sur l'état des objets.

    Une fonction de recherche basée sur la comparaison "profonde" d'objets n'existe pas dans TList. Il serait préférable de créer une classe container spécifique.

    Cette réponse te convient-elle ?

    cdlt

    e-ric

    M E N S . A G I T A T . M O L E M
    Debian 64bit, Lazarus + FPC -> n'oubliez pas de consulter les FAQ Delphi et Pascal ainsi que les cours et tutoriels Delphi et Pascal

    "La théorie, c'est quand on sait tout, mais que rien ne marche. La pratique, c'est quand tout marche, mais qu'on ne sait pas pourquoi. En informatique, la théorie et la pratique sont réunies: rien ne marche et on ne sait pas pourquoi!".
    Mais Emmanuel Kant disait aussi : "La théorie sans la pratique est inutile, la pratique sans la théorie est aveugle."

  6. #6
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    1 132
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 132
    Par défaut
    Effectivement, comme le précise e-ric, IndexOf fait une comparaison de pointeurs

    donc si tu as :
    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
    var
      obj1, obj2, obj3:TMonObj;
      liste:TList  
    begin
      ...
     
      obj1 := TMonObj.create;
      obj2 := obj1;
      obj3.assign(obj1);
     
      liste.Add(obj1);
      ind := liste.IndexOf(obj1); // ind = 0
      ind := liste.IndexOf(obj2); // ind = 0
      ind := liste.IndexOf(obj3); // ind = -1
     
      ...
     
    end;
    car obj3 aura les mêmes valeurs de propriétés que obj1 mais pas la même adresse mémoire alors que obj2 pointe sur obj1

    Si tu ne peux pas modifier la classe d'objet dans la liste et si tu ne peux pas faire un dérivé de TList, il reste la solution de faire une fonction de recherche à laquelle tu passeras les 2 objets (la liste et l'objet recherché)
    par exemple comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function marecherche(alist:TList; aObj:TMonObj):integer;
    begin
      for Result := 0 to alist.Count-1 do 
        if MaComparaison(alist[Result] , aObj) then  Exit;
     
      Result := -1;
    end;

  7. #7
    Membre confirmé
    Inscrit en
    Octobre 2005
    Messages
    180
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 180
    Par défaut
    OK un grand merci a tous alors dommage qu'il n'existe pas un classe de base fesant déja ca je pense que c'est pourtant utile à plus d'une occaz...

    Merci

  8. #8
    Expert confirmé Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Par défaut
    Bonjour,

    Il n'y a effectivement pas d'implémentation standard d'une fonction d'index couplée à un "callback" de comparaison.

    C'est une des raisons (avec aussi la facilité de debug) pour laquelle j'utilise systématiquement des Tstringlist au lieu de Tlist. Il faut à la création ou à la modification de chaque objet de la liste, créer une chaine de comparaison à partir des données de l'objet et la mettre dans la tstringList.

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    var tsl:tstringlist ;
    // ajout d'un objet
    tsl.add(myobject.getCompareString,myobject) ;
     
    // recherche
    i:=tsl.indexof(searchedString) ;
    if i>=0 then foundObject:=Tmyobject(tsl.objects[i]) else foundObject:=nil ;
    ...

Discussions similaires

  1. [TList] Double référencement
    Par Pedro dans le forum Langage
    Réponses: 5
    Dernier message: 28/07/2004, 13h14
  2. [C#] Prob IndexOf sous Pocket Pc avec des guillemets
    Par freddyboy dans le forum Windows Mobile
    Réponses: 7
    Dernier message: 10/06/2004, 09h57
  3. TList et redimensionnement ?
    Par cpdump dans le forum Langage
    Réponses: 3
    Dernier message: 05/05/2004, 16h54
  4. TList lente
    Par localhost dans le forum C++Builder
    Réponses: 5
    Dernier message: 17/02/2004, 01h01
  5. Transtyper element d'1 variable pointant sur TList?
    Par Cornell dans le forum Langage
    Réponses: 2
    Dernier message: 25/02/2003, 22h53

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