[Delphi] array sorteren

Pagina: 1
Acties:
  • 124 views sinds 30-01-2008
  • Reageer

  • spaceboy
  • Registratie: Februari 2001
  • Laatst online: 17:53

spaceboy

Op grote hoogte

Topicstarter
In Delphi kun je met de listbox een aantal strings alfabetisch sorteren. De property "Sorted" volstaat dan.

Nu wil ik graag een aantal arrays (simpele array, per regel 1 string en 1 integer) laten sorteren op de string in de array. Weet iemand hoe ik dat eenvoudig voor elkaar krijg?

Aan bovenstaande tekst kunnen geen rechten worden ontleend. Aan de tekst hieronder wel.


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 14:22

Tomatoman

Fulltime prutser

Daarvoor moet je zelf de logica schrijven. Da's trouwens niet erg moeilijk als je gebruik maakt van een TStringList. Alle array-elementen naar een TStringList kopiëren via AddObject (waarbij je als tweede parameter de index in de array meegeeft), Sorted veranderen naar True en ten slotte alle elementen weer terugkopiën naar de oorspronkelijke array.

Een goede grap mag vrienden kosten.


  • spaceboy
  • Registratie: Februari 2001
  • Laatst online: 17:53

spaceboy

Op grote hoogte

Topicstarter
tomatoman schreef op 26 oktober 2003 @ 15:28:
Daarvoor moet je zelf de logica schrijven. Da's trouwens niet erg moeilijk als je gebruik maakt van een TStringList. Alle array-elementen naar een TStringList kopiëren via AddObject (waarbij je als tweede parameter de index in de array meegeeft), Sorted veranderen naar True en ten slotte alle elementen weer terugkopiën naar de oorspronkelijke array.
Thanks. Nog een hele domme vraag. WAAR zit het TStringList object?? Ik heb alle tabbladen van de componenten 3x afgestruind. Zelfs zoeken in die bladen levert niets op. Terwijl in de help-functie van Delphi ook gewoon over TStringLists wordt gesproken alsof elke debiel weet waar het componentje zit... :?

Edit: ik bedenk me nu dat het misschien geen component is, maar alleen een type variabele??

[ Voor 7% gewijzigd door spaceboy op 26-10-2003 15:58 ]

Aan bovenstaande tekst kunnen geen rechten worden ontleend. Aan de tekst hieronder wel.


  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

spaceboy schreef op 26 October 2003 @ 15:54:
Edit: ik bedenk me nu dat het misschien geen component is, maar alleen een type variabele??
Lijkt me een hele goede gedachte. Niet alles is een component wat je op je form kan gooien. De Delphi Help (F1) kan je er vast meer over vertellen.

We adore chaos because we like to restore order - M.C. Escher


  • spaceboy
  • Registratie: Februari 2001
  • Laatst online: 17:53

spaceboy

Op grote hoogte

Topicstarter
tomatoman schreef op 26 October 2003 @ 15:28:
...Alle array-elementen naar een TStringList kopiëren via AddObject (waarbij je als tweede parameter de index in de array meegeeft)...
Eh ik snap niet helemaal wat je bedoelt. Ik heb dus:
code:
1
2
3
4
5
6
7
8
9
rData = record
             naam: string[50];
             nummer: integer;
             end;

aData : array[1..100] of rData;
slData: stringlist;

slData.AddObject(...???)


Wat moet er op de vraagtekens?

Aan bovenstaande tekst kunnen geen rechten worden ontleend. Aan de tekst hieronder wel.


Verwijderd

Delphi:
1
slData.AddObject(naam, TObject(nummer));


Overigens moet je wel zelf eerst die instantie van die StringList creeëren.

[ Voor 39% gewijzigd door Verwijderd op 26-10-2003 16:16 ]


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 14:22

Tomatoman

Fulltime prutser

Ten eerste moet je een object creëren. Dat doe je door de constructor aan te roepen, die voor bijna ieder object Create heet. Je gaat een object maken van de klasse TStringList (dus met een T ervoor). Als je ermee klaar bent, moet je het ook weer vernietigen, want anders wordt het geheugen dat het object gebruikt niet vrijgegeven --> geheugenlek. Dat ziet er als volgt uit:
Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var
  DataStrings: TStringList;
begin
  DataStrings := TStringList.Create;  // object creeren via de constructor
  { Met een try-finally constructie zorg je ervoor dat het gedeelte in het
    finally-blok altijd wordt uitgevoerd, zelfs als er een exception
    optreedt. Hiermee garandeer je dat de TStringList weer wordt vernietigd
    en het geheugen vrijgegeven. }
  try
    { Hier ga je wat doen met DataStrings }
  finally
    DataStrings.Free;  // object vernietigen via de destructor
  end;
end;
In de helpfiles kun je lezen dat TStringList.AddObject twee argumenten verwacht: een string en een TObject. Nu is AObject eigenlijk niets meer dan een pointer naar de geheugenplek waar het daadwerkelijke object aanwezig is. Aangezien een pointer even groot is als een Integer (beide 32 bits), kun je AObject misbruiken om er een Integer in op te slaan in plaats van een TObject. Daarvoor moet je de compiler wel expliciet vertellen dat je dat van plan bent, want anders gaat hij klagen dat je een Integer als argument geeft terwijl hij een TObject verwacht. Dat doe je via typecasting:
Delphi:
1
2
3
4
5
6
7
8
9
{ Een Integer typecasten als een TObject: }
var
  i: Integer;
  Obj: TObject;
begin
  i := 1; // zomaar een waarde;
  Obj := TObject(i);
  { In de variabele Obj is nu de waarde 1 opgeslagen. }
end;

Terug naar TStringList. Je wilt in de string list alle strings opslaan met bij iedere string het bijbehorende nummer. Het nummer gaan we we in AObject stoppen.
Delphi:
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
type
  TDataRec = record
    Naam: string;
    Nummer: Integer;
  end;

  TDataArr: array[0..99] of TDataRec;  // let op: het eerste element is 0!

procedure SorteerData(var DataArr: TDataArr);
var
  DataStrings: TStringList;
  i: Integer;
begin
  DataStrings := TStringList.Create;
  try
    { Alle records toevoegen }
    for i := 0 to High(DataArr) do
      DataStrings.AddObject(DataArr[i].Naam, TObject(DataArr[i].Nummer));
    { Sorteren }
    DataStrings.Sorted := True;
    { Gesorteerde gegevens terugzetten in DataArr }
    for i := 0 to DataStrings.Count - 1 do
    begin
      DataArr[i].Naam := DataStrings.Strings[i];
      DataArr[i].Nummer := Integer(DataStrings.Objects[i]);  // typecasting
    end;
  finally
    DataStrings.Free;
  end;
end;
Nu kun je de procedure heel gemakkelijk aanroepen:
Delphi:
31
32
33
34
35
36
37
38
39
40
41
42
43
44
var
  MijnData: TDataArr;
  i, Rnd: Integer;
begin
  { MijnData vullen met zomaar wat onzin }
  for i := 0 to High(MijnData) do
  begin
    Rnd := Random(1000);
    MijnData[i].Naam := 'Test' + IntToStr(Rnd);
    MijnData[i].Nummer := i;
  end;
  { Sorteerprocedure aanroepen }
  SorteerData(MijnData);
end;

[ Voor 1% gewijzigd door Tomatoman op 26-10-2003 16:49 . Reden: haakje vergeten in code ]

Een goede grap mag vrienden kosten.


  • spaceboy
  • Registratie: Februari 2001
  • Laatst online: 17:53

spaceboy

Op grote hoogte

Topicstarter
He helemaal super Tomatoman! Het werkt en is 100% duidelijk! Thanks!

Aan bovenstaande tekst kunnen geen rechten worden ontleend. Aan de tekst hieronder wel.

Pagina: 1