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

Langage Delphi Discussion :

Tri avec TObjectList


Sujet :

Langage Delphi

  1. #1
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut Tri avec TObjectList
    Bonjour,

    J'utilse le code suivant pour effectuer des tris sur une TObjectList :
    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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    type      TTruc = class
              public
                Titre   : string;
                Texte   : string;
                NbPages : word;
                constructor Create( iTitre, iTexte : string;  iNbPages  : word);
              end;
    
              TListeDeTrucs = class(TObjectList)
              private
                function  GetItem(Index: Integer): TTruc;
                procedure SetItem(Index: Integer; const Value: TTruc);
                function  fCompareAlphaTitres(Item1, Item2: Pointer): Integer;
              public
                function  Add(AObject: TTruc): Integer;
                procedure Insert(Index: Integer; AObject: TObject);
                property  Items[Index: Integer]: TTruc read GetItem write SetItem; default;
              end;
    
    // TTruc :
    
    constructor TTruc.Create( iTitre, iTexte : string; iNbPages  : word);
    begin       Titre   := iTitre;
                Texte   := iTexte;
                NbPages := iNbPages;
    end;
    
    // TListeDeTrucs :
    
    function  TListeDeTrucs.fCompareAlphaTitres(Item1, Item2: Pointer): Integer;
    begin     if TTruc(item1).Titre > TTruc(item2).Titre then Result := +1 else
              if TTruc(item1).Titre < TTruc(item2).Titre then Result := -1
              else Result := 0;
    end;
    
    function  fCompareAlphaTitres(Item1, Item2: Pointer): Integer;
    begin     if TTruc(item1).Titre > TTruc(item2).Titre then Result := +1 else
              if TTruc(item1).Titre < TTruc(item2).Titre then Result := -1
              else Result := 0;
    end;
    
    function  fCompareNumNbPages(Item1, Item2: Pointer): Integer;
    begin     if TTruc(item1).NbPages > TTruc(item2).NbPages then Result := +1 else
              if TTruc(item1).NbPages < TTruc(item2).NbPages then Result := -1
              else Result := 0;
    end;
    function  TListeDeTrucs.Add(AObject: TTruc): Integer;
    begin     result := inherited Add(AObject); end;
     
    procedure TListeDeTrucs.Insert(Index: Integer; AObject: TObject);
    begin     inherited Insert(index, AObject); end;
    
    function  TListeDeTrucs.GetItem(Index: Integer): TTruc;
    begin     result := TTruc(inherited GetItem(index)); end;
    
    procedure TListeDeTrucs.SetItem(Index: Integer; const Value: TTruc);
    begin     inherited setItem(index, value); end;
    
    //---------Utilisation :
    
    var       Li1 : TListeDeTrucs;
    
    procedure TfrmTriSLObj.btnCeerListeDeTrucsClick(Sender: TObject);
    var       i    : integer;
              sNum : string;
              nbPages : word;
    begin     if not Assigned(Li1) Then li1 := TListeDeTrucs.Create(true);
              li1.OwnsObjects:=True;
              Randomize;
              for i:=1 to 10 do
              begin sNum:=intToStr(i);
                    nbPages:=Random(100);
                    li1.Add(TTruc.Create('Titre'+sNum, 'Texte'+sNum, nbPages ));
              end;
              for i := 0 to li1.count - 1 do
              begin red1.lines.Add(li1.items[i].Titre+' '+li1.items[i].Texte );
              end;
    
    end;
    
    procedure TfrmTriSLObj.btnTrierClick(Sender: TObject);
    var       FCompareTri : TListSortCompare;
              i : word;
    begin     //FCompareTri:=li1.fCompareAlphaTitres; //< NE MARCHE PAS [Erreur] uTriSLObj.pas(201): Types incompatibles : procédure normale et pointeur de méthode
              //Li1.Sort(FCompareTri);
              Li1.Sort(@fCompareAlphaTitres); //< Marche
    
              red1.lines.Add('');
              for i := 0 to li1.count - 1 do
              begin red1.lines.Add(li1.items[i].Titre);
              end;
    
              Li1.Sort(@fCompareNumNbPages); //< Marche
              red1.lines.Add('');
              for i := 0 to li1.count - 1 do
              begin red1.lines.Add(li1.items[i].Titre+' : '+intToStr(li1.items[i].NbPages));
              end;
    end;
    
    procedure TfrmTriSLObj.FormClose(Sender: TObject;
      var Action: TCloseAction);
    begin     if Assigned(li1) Then FreeAndNil(li1);
    end;
    ... où j'ai, dans un 1er temps, voulu encapsuler dans TListeDeTrucs la fonction de comparaison (TListeDeTrucs.fCompareAlphaTitres() ) à utiliser par Sort mais le compilo n'a pas été d'accord.
    ... et dans un 2ème temps j'ai isolé les fonctions de comparaison (en vert ci-dessus) et cela a marché.

    Questions :
    1) Pourquoi cela n'a pas marché dans le 1er cas ?
    2) Comment faire pour encapsuler les fonctions de comparaison dans le type TListeDeTrucs ?
    3) Et, en supposant que mon encapsulage aie été correct, quelle est la bonne syntaxe pour appeler ces fonctions lors l'instruction "Li1.Sort(fonctionDeComparaison)" ?

    A+
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  2. #2
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 862
    Points : 11 321
    Points
    11 321
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    méthode d'objet et procédure normale sont incompatibles ; mais l'article de Laurent Dardenne ici permet de se sortir de l'ornière !

    tu peux aussi plus simplement utiliser des méthodes qui appelleront Sort avec une fonction de comparaison interne à la méthode, qui ne sera donc pas une méthode d'objet :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    procedure MaListe.TrieSelonNbDePages;
    function  fCompareNumNbPages(Item1, Item2: Pointer): Integer;
    begin     if TTruc(item1).NbPages > TTruc(item2).NbPages then Result := +1 else
              if TTruc(item1).NbPages < TTruc(item2).NbPages then Result := -1
              else Result := 0;
    end;
    begin
      Sort(@fCompareNumNbPages);
    end;
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  3. #3
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Re-bonjour,

    Merci Tourlourou :
    tu peux aussi plus simplement utiliser des méthodes qui appelleront Sort avec une fonction de comparaison interne à la méthode
    ... vu! Effectivement c'est plus simple ... fallait y penser.

    En tous cas merci.

    A+
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  4. #4
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 862
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 862
    Points : 11 321
    Points
    11 321
    Billets dans le blog
    6
    Par défaut
    oups, j'ai pê raté le lien que je voulais mettre vers le tuto de Sébastien Doeraene

    mais le plus simple est dit !

    à bientôt
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème de tri avec analyse croisée
    Par drthodt dans le forum Access
    Réponses: 2
    Dernier message: 18/10/2005, 16h23
  2. formule de calcul du TRI avec PL/SQL
    Par mongilotti dans le forum Algorithmes et structures de données
    Réponses: 15
    Dernier message: 30/07/2005, 20h23
  3. Pb de tri avec champs vide
    Par nesbla dans le forum Langage SQL
    Réponses: 2
    Dernier message: 01/06/2004, 17h42
  4. tri avec l'ordre UPDATE et incrementation d'une colonne
    Par Staron dans le forum Langage SQL
    Réponses: 3
    Dernier message: 17/02/2004, 08h48
  5. tri avec les champs vides en dernier
    Par r-zo dans le forum Requêtes
    Réponses: 11
    Dernier message: 03/09/2003, 13h40

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