Page 1 of 2 1 2 LastLast
Results 1 to 15 of 16

Thread: TList en Indexof

  1. #1

    TList en Indexof

    Uitgaande van het artikel op

    http://www.nldelphi.com/Forum/showth...hlight=indexof

    wil ik de indexof-functie van TList gebruiken.....een beetje help
    zou fantastisch zijn:

    Code:
    unit Unit1;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, Buttons;
    
    type
      TForm1 = class(TForm)
        BitBtn1: TBitBtn;
        procedure BitBtn1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    
    type
      TKoe = record
        big, neus: Integer;
        jantje: string;
      end;
      PKoe = ^TKoe;
    
    var
      Form1: TForm1;
      FList: TList;
    
    implementation
    
    {$R *.dfm}
    
    procedure AddItem;
    var
      Koe: PKoe;
    begin
      New(Koe);
    
      Koe^.big := 10;
      Koe^.neus := 11;
      Koe^.jantje := 'nieuw';
    
      FList := TList.Create; //moet erbij
      FList.Add(Koe);
    end;
    
    procedure TForm1.BitBtn1Click(Sender: TObject);
    var
      Koe1: PKoe;
    begin
      AddItem;
    
      New(Koe1);
      Koe1^.big := 10;
      Koe1^.neus := 11;
      Koe1^.jantje := 'nieuw';
      //if MyList.IndexOf(MyObject)=-1 then MyList.Add(MyObject);
    
      if FList.IndexOf(Koe1) > -1 then Form1.Caption := 'gevonden';
    end;
    
    end.
    ....wordt toch niet gevonden.......

    bedankt alvast

  2. #2
    Waarom zet je ieder item in een aparte list? Maak 1 list aan en voeg daar alle items toe want anders kan je nooit iets anders vinden dan het laatst toegevoegde item
    DeX 3 Delphi := The ease of VB with the power of C; Zoekt en gij zult vinden

  3. #3

    greeg een voorbeeld, Henkie

    Hallo Henkie,

    Kun je een klein voorbeeldje geven.
    Ik wil met tlist en indexof werken.

    Ik zit al een poosje met dit 'probleem'.......

    Bedankt alvast

  4. #4
    List aanmaken in de constructor ipv telkens in AddItem
    DeX 3 Delphi := The ease of VB with the power of C; Zoekt en gij zult vinden

  5. #5
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    delphi Code:
    1. procedure TForm7.FormCreate(Sender: TObject);
    2. begin
    3.   FList := TList.Create; //moet erbij
    4. end;
    5.  
    6. procedure TForm7.Button1Click(Sender: TObject);
    7. var
    8.   Koe1: PKoe;
    9. begin
    10.   New(Koe1);
    11.   AddItem(Koe1);
    12.   if FList.IndexOf(Koe1) > -1 then label1.Caption := 'gevonden';
    13. end;
    14.  
    15. procedure AddItem(Koe: PKoe);
    16. begin
    17.   Koe^.big := 10;
    18.   Koe^.neus := 11;
    19.   Koe^.jantje := 'nieuw';
    20.   FList.Add(Koe);
    21. end;
    Alleen hoe ga je dit weer vrijgeven?
    Delphi is great. Lazarus is more powerfull

  6. #6
    Silly member NGLN's Avatar
    Join Date
    Aug 2004
    Location
    Werkendam
    Posts
    5,133
    (Sender as TNLDUser).Signature := 'Groeten van Albert';

  7. #7
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Is dit nu een stuk sneller dan het gebruik van een dynamische record array?
    Delphi is great. Lazarus is more powerfull

  8. #8
    Dat kan heel goed. Een list heeft intern ook weer een dynamische array, maar dat is een array van pointers. Bovendien wordt de capaciteit daarvan in sprongen bijgesteld, en daardoor heb je minder (her)allocaties.
    Natuurlijk is het het best als je van te voren weet hoe groot je lijst gaat worden. Je kunt dan in één keer je array de juiste grootte geven, of de capacity van je list groot genoeg maken. In dat geval is de array waarschijnlijk sneller. Maar ik denk dat je het verschil nauwelijks kunt meten tenzij je echt met vele duizenden records aan de slag gaat.
    1+1=b

  9. #9
    John Kuiper
    Join Date
    Apr 2007
    Location
    Almere
    Posts
    8,747
    Oke, maar op het probleem van philips10 terug te komen. Als je naam van het object steeds 'Koe' is, dan kan je met indexof() nooit de daadwerkelijke pointer terug vinden, die je op dat moment nodig hebt Je maakt n.l. telkens een nieuwer pointer aan met dezelfde objectnaam. Het is of gebruikmaken van een eigen zoekfunctie of van TList afstappen en gebruik maken van: Koe : array of TKoe
    Delphi is great. Lazarus is more powerfull

  10. #10
    Silly member NGLN's Avatar
    Join Date
    Aug 2004
    Location
    Werkendam
    Posts
    5,133
    Quote Originally Posted by jkuiper View Post
    Als je naam van het object steeds 'Koe' is ... Je maakt n.l. telkens een nieuwer pointer aan met dezelfde objectnaam.
    Er is hierboven geen sprake van een object of iets dat je een naam kan geven.

    Ik vermoed dat je bedoeld dat als je geen extra referentie bijhoudt naar een aangemaakte/toegevoegde PKoe, dat de standaard werking van TList.IndexOf inderdaad geen zin heeft. Die vraagt namelijk als parameter een pointer, in dit geval een pointer naar een instantie van een TKoe-record, en als je die alleen bijhoudt in de TList, dan heb je geen referentie waarnaar je moet zoeken.

    Je hebt gelijk dat je dan een eigen zoekfunctie moet maken, maar dat zou je ook moeten indien je een array i.p.v. een TList gebruikt.
    (Sender as TNLDUser).Signature := 'Groeten van Albert';

  11. #11
    Silly member NGLN's Avatar
    Join Date
    Aug 2004
    Location
    Werkendam
    Posts
    5,133
    Om het even samen te vatten, hierbij een testprogrammaatje. Begin een nieuwe Applicatie, zet een Button en een Memo op je form, kopieer onderstaande code in je editor en wijs OnCreate, OnDestroy en Button1.OnClick toe:
    Delphi Code:
    1. unit Unit1;
    2.  
    3. interface
    4.  
    5. uses
    6.   SysUtils, Classes, Forms, StdCtrls, Controls;
    7.  
    8. type
    9.   PKoe = ^TKoe;
    10.   TKoe = record
    11.     Big: Integer;
    12.     Neus: Integer;
    13.     Jantje: String;
    14.   end;
    15.  
    16.   TForm1 = class(TForm)
    17.     Memo1: TMemo;
    18.     Button1: TButton;
    19.     procedure FormCreate(Sender: TObject);  { Form1.OnCreate event handler }
    20.     procedure FormDestroy(Sender: TObject);  { Form1.OnDestroy event handler }
    21.     procedure Button1Click(Sender: TObject);  { Button1.OnClick event handler }
    22.   private
    23.     FList: TList;
    24.     procedure AddItem(ABig, ANeus: Integer; const AJantje: String);
    25.     procedure ClearItems;
    26.     function FindItemForBig(ABig: Integer): PKoe;
    27.   end;
    28.  
    29. var
    30.   Form1: TForm1;
    31.  
    32. implementation
    33.  
    34. {$R *.dfm}
    35.  
    36. procedure TForm1.AddItem(ABig, ANeus: Integer; const AJantje: String);
    37. var
    38.   Koe: PKoe;
    39. begin
    40.   Koe := New(PKoe);
    41.   Koe^.Big := ABig;   { Dit is de officiële notatie }
    42.   Koe.Neus := ANeus;  { Maar dit mag ook, de compiler snapt dat je ^ bedoeld }
    43.   Koe.Jantje := AJantje;
    44.   FList.Add(Koe);
    45. end;
    46.  
    47. procedure TForm1.Button1Click(Sender: TObject); { Het e.e.a. eens even testen }
    48. var
    49.   Koe: PKoe;
    50.   Index: Integer;
    51. begin
    52.   AddItem(10, 11, 'Aap');
    53.   AddItem(12, 13, 'Noot');
    54.   AddItem(14, 15, 'Mies');
    55.   AddItem(16, 17, 'Laatste');
    56.   Koe := FindItemForBig(15);
    57.   if Koe = nil then
    58.     Memo1.Lines.Add('Big = 15 niet gevonden');
    59.   Koe := FindItemForBig(14);
    60.   if Koe <> nil then
    61.   begin
    62.     Memo1.Lines.Add('Als Big = 14, dan is Jantje: ' + Koe.Jantje);
    63.     Index := FList.IndexOf(Koe);
    64.     Memo1.Lines.Add('En de index daarvan in FList = ' + IntToStr(Index));
    65.   end;
    66. end;
    67.  
    68. procedure TForm1.ClearItems;
    69. var
    70.   i: Integer;
    71. begin
    72.   for i := 0 to FList.Count - 1 do
    73.     Dispose(PKoe(FList[i]));
    74. end;
    75.  
    76. function TForm1.FindItemForBig(ABig: Integer): PKoe;
    77. var
    78.   i: Integer;
    79. begin
    80.   Result := nil;
    81.   for i := 0 to FList.Count - 1 do
    82.     if PKoe(FList[i]).Big = ABig then
    83.     begin
    84.       Result := FList[i];
    85.       Break;
    86.     end;
    87. end;
    88.  
    89. procedure TForm1.FormCreate(Sender: TObject);
    90. begin
    91.   FList := TList.Create;
    92. end;
    93.  
    94. procedure TForm1.FormDestroy(Sender: TObject);
    95. begin
    96.   ClearItems;
    97.   FList.Free;
    98. end;
    99.  
    100. end.
    Zo zie je IndexOf aan het werk.

    Let op dat dit nog geen waterdichte implementatie van TList van records is!! Zo mag je bijvoorbeeld nooit FList.Delete(Index) gebruiken, want de pointer wordt daarmee uit de lijst verwijderd, maar het geheugen waar die pointer naar verwijst niet. Om een volledig verantwoorde TList van records te maken, moet je eigenlijk je eigen afstammeling van TList maken.

    Afijn, tot zover de theorie. Ik begrijp dat je liever een TList dan een Array wilt gebruiken, want TList is gewoon zoveel handiger. Echter, het vraagt dus wel wat aandacht om een TList voor het beheren van records te maken.
    Waar wil je dit voor gaan gebruiken? Moet je je gegevens in records opslaan, of mogen dat ook objecten zijn?
    (Sender as TNLDUser).Signature := 'Groeten van Albert';

  12. #12

    Zoeken met TFList en IndexOf, zonder for-next-lus...toch niet?

    Ik had gehoopt, dat je met TList en Indexof, zonder een for-next-lus bv
    Koe.Neus kon finden


    Code:
    begin
     .......  
      if  FList.IndexOf(Koe1.big) = 10 then label1.Caption := 'gevonden';
    end;
    maar dat werkt dus niet omdat Koe1.big een integer is en geen pointer.

    Enig idee?

    Wederom bedankt

  13. #13
    Silly member NGLN's Avatar
    Join Date
    Aug 2004
    Location
    Werkendam
    Posts
    5,133
    Maak dan een alternatief voor FindItemForBig die niet een PKoe, maar de Index retourneert:
    Delphi Code:
    1. function TForm1.IndexOfBig(ABig: Integer): Integer;
    2. var
    3.   i: Integer;
    4. begin
    5.   Result := -1;
    6.   for i := 0 to FList.Count - 1 do
    7.     if PKoe(FList[i]).Big = ABig then
    8.     begin
    9.       Result := i;
    10.       Break;
    11.     end;
    12. end;
    (Sender as TNLDUser).Signature := 'Groeten van Albert';

  14. #14

    niet zonder for..net-lust...toch prima

    Hallo NGLN

    Goed nagedacht...prima.

    Blijkbaar gaat het toch niet zonder for...next.

    Heb veel geleerd.

    Bedankt NGLN en allemaal.

  15. #15

    zoals bij een TConboBox

    Ik doelde naar zoeits als bij een TComboBox:

    Code:
    if Combobox.items.IndexOf('hello') = -1 then
    Ik weet, dat hier om maar een serie van items
    Stringlist binnenin een TComboBox gaat....

    Maakt niet uit. Ben tevreden zo.

    Bedankt
    Last edited by Philips10; 08-Feb-10 at 15:04. Reason: vergeten als code

Page 1 of 2 1 2 LastLast

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •