![]() |
Mehrdimensionaler Array wie in PHP möglich?
Hallo Wissende,
ich bin gerade dabei eine Tabellenberechnung für eine Sportart aus php nach Delphi zu portieren. In der mir vorliegenden Source wird mit mehrdimensionalen Arrays gearbeitet. Nun bin ich am Grübeln, wie ich das am cleversten übersetze. Hier mal ein Fetzen aus der Source:
Delphi-Quellcode:
$results ist ein mehrdimensionales Array
$results[$team_a_id]['punkte'] += $pts_g;
$results[$team_b_id]['punkte'] += $pts_v; $results[$team_a_id]['siege'] += 1; $results[$team_b_id]['verloren'] += 1; $team_a_id ist eine Variable, die die Team-Id des Teams A beinhaltet $team_b_id ist eine Variable, die die Team-Id des Teams B beinhaltet 'punkte' steht für die Punkte, die es bei einem Sieg gibt usw Nun kann ich ja sicher in Delphi keinen solchen Array erzeugen, bei dem ich die Inhalte über die Namen anspreche. Durch ein Array iteriert man doch immer über einen Index. Oder? Ich schwanke nun, ob ich einen Mehrdimensionalen Array benutzen soll oder mir ein Record bastle. Dabei Frage ich mich natürlich auch, wie ich dann zum Beispiel später die Einträge nach den Punkten der Teams aufsteigend sortieren kann (Array/Record) und wie ich einen Teameintrag später noch ansprechen kann, ohne jedes mal komplett durch das Array/Record über eine Schleife, in der ich die jeweilge Team-Id prüfe, ansprechen kann. Für helfende Infos bedanke ich mich im voraus. Sollte mehr Sourcecode benötigt werden, stelle ich auch gern mehr zur Verfügung. |
AW: Mehrdimensionaler Array wie in PHP möglich?
Hallo,
eine Array of Record. Wobei der Index im Array Deine Team_ID ist und das Record die benötigten Informationen bereit hält. Du kannst auch eine TList verwenden mit Klassen die deine Information bereit hält. Dort kannst du dann ein Customsort durchführen. Die Methode must du selber implementieren. Sie gibt dir immer zwei Listen-Elemente und du muss sagen welches vor dem anderen sein soll. Gruß, Chris |
AW: Mehrdimensionaler Array wie in PHP möglich?
Delphi-Quellcode:
Das wäre jetzt dreidimensional.
array [1..2,1..3,1..10] of ...
|
AW: Mehrdimensionaler Array wie in PHP möglich?
Man kann auch solche Konstrukte verwenden, solange man die Übersicht behält (was nicht immer ganz einfach ist):
Delphi-Quellcode:
type
TKategorie = (Punkte,Siege,verloren); TKatArray = array[TKategorie] of integer; TDynArray = array of TKatArray; procedure TfrmTest.FormCreate(Sender: TObject); var Arr: TDynArray; i: integer; begin SetLength(Arr,2); Arr[0][Punkte] := 1; Arr[0][Siege] := 0; Arr[0][verloren] := 0; Arr[1][Punkte] := 3; Arr[1][Siege] := 1; Arr[1][verloren] := 0; for i := Low(Arr) to High(Arr) do ShowMessage(Format('Punkte: %d, Siege: %d, verloren: %d',[Arr[i][punkte],Arr[i][Siege],Arr[i][verloren]])); SetLength(Arr,0); end; |
AW: Mehrdimensionaler Array wie in PHP möglich?
Delphi-Quellcode:
.
variable['text']
sowas nennt sich assoziatives Array für kann man eine TStringList mißbauchen - wenn Stringvalue: Name > Value (Strings = 'Name=Value') - Strings/Zeile = Name und den Value ins Objekt oder einfach mal nach ![]() ![]() ![]() |
AW: Mehrdimensionaler Array wie in PHP möglich?
Oder ein Dictionary / HashTable :gruebel:
|
AW: Mehrdimensionaler Array wie in PHP möglich?
Hallo Wissende,
ich habe es nun einigermaßen erfolgreich von php nach Delphi übersetzen können, indem ich eine Stringlist mit Objekten befülle. Das klappt soweit ganz gut. Nun habe ich aber noch das Problem des Sortierens und des direkten Vergleichs bei Punktgleicheit. Hier mal mein Code für einen prüfenden Blick. Ist zum Teil kommentiert. Ich stehe natürlich für Rückfragen zur Verfügung:
Delphi-Quellcode:
//dies ist die klasse für das erzeugen der objekte für die stringliste
unit rank_data; interface uses classes, XmlIntf, SysUtils, Variants; type TRankData=class public TeamName : String; Won : Integer; Loss : Integer; Draw : Integer; Points : Integer; Goals : Integer; Goals_Away : Integer; ReGoals : Integer; DirGoals : Integer; Games : Integer; constructor Create(aName,anId: String); overload; constructor Create; overload; end; implementation { TRankData } constructor TRankData.Create(aName, anId: String); begin inherited Create; TeamName := aName; end; constructor TRankData.Create; begin inherited; end; end.
Delphi-Quellcode:
Hier noch das Ausgabeergebnis meiner ShowMessage, welches inhaltlich korrekt aber leider noch nicht sortiert ist:
//hier die prozedure, welche die daten aus db ausliest und in eine stringlist schreibt
procedure TForm1.btn_calculateClick(Sender: TObject); var int_pts_g, int_pts_u, int_pts_v, int_pts_vl, i : integer; str_league_id, str_round : String; str_TName_a, str_TName_b : String; str_team_a_id, str_team_b_id : String; int_result_a, int_result_b, int_end_periode : integer; var_holder : Variant; RankDataA, RankDataB : TRankData; intListPosA, intListPosB : integer; begin //globale rankliste leeren->berücksichtigt nicht die schon vorhandenen objekte RankList.Clear; //besorgen des spieltages BIS zu dem berechnet werden soll if not(cmb_calc_from.Text <> '') and not(cmb_calc_to.Text <> '') then begin MessageDlg('Please select Round From and Round To!',mtInformation,[mbok],0); exit; end; //internes beschaffen der league_id und round str_league_id := sel_match.GetLeagueIdByLeagueName(cmb_leagues.Text); str_round := cmb_calc_to.Text; // step 1: lade die wertigkeiten - kann man noch optimieren //wir holen uns die wertigkeit eines spieles aus der db with dm.ADOQuery1 do begin Close; sql.Clear; sql.Add('SELECT * FROM leagues WHERE id=' + str_league_id); Open; ExecSQL; var_holder:= FieldbyName('pts_won').AsVariant; int_pts_g := VarToIntDef(var_holder, 0); var_holder:= FieldbyName('pts_draw').AsVariant; int_pts_u := VarToIntDef(var_holder, 0); var_holder:= FieldbyName('pts_loss').AsVariant; int_pts_v := VarToIntDef(var_holder, 0); // step 2: lade alle ergebnisse bis zum entsprechenden spieltag und die teamnamen gleich dazu Close; sql.Clear; sql.Add('SELECT r.league_id, r.season_id, r.round, r.team_a_id, r.team_b_id, r.result_a, r.result_b, end_in_periode ' + 'FROM matches r, teams t_a, teams t_b ' + 'WHERE r.league_id = ' + str_league_id + ' AND r.season_id = 6' + ' AND r.round <= ' + str_round + ' AND r.result_a > -1' + ' AND r.result_b > -1' + ' AND r.team_a_id = t_a.id' + ' AND r.team_b_id = t_b.id' + ' ORDER BY r.round'); Open; ExecSQL; while not(Eof) do begin // lokale variablen int_pts_vl := 0; //punkte verloren für schleife reseten str_team_a_id := FieldbyName('team_a_id').AsString; str_team_b_id := FieldbyName('team_b_id').AsString; int_result_a := FieldbyName('result_a').AsInteger; int_result_b := FieldbyName('result_b').AsInteger; str_TName_a := sel_match.GetTeamNameById(str_team_a_id); str_TName_b := sel_match.GetTeamNameById(str_team_b_id); var_holder := FieldbyName('end_in_periode').AsVariant; int_end_periode := VarToIntDef(var_holder, 0); //bei verloren nach verlängerung gibts trotzdem 1 punkt!!! case int_end_periode of 0,1,2,3 : int_pts_vl := int_pts_v; else int_pts_vl := int_pts_v + 1; end; if not(RankList.IndexOf(str_team_a_id) > -1) then begin RankDataA := TRankData.Create(str_TName_a,str_team_a_id); //intListPosA := RankList.Add(str_team_a_id); intListPosA := RankList.AddObject(str_team_a_id, RankDataA); end else RankDataA := (RankList.Objects[RankList.IndexOf(str_team_a_id)] as TRankData); if not(RankList.IndexOf(str_team_b_id) > -1) then begin RankDataB := TRankData.Create(str_TName_b,str_team_b_id); //intListPosA := RankList.Add(str_team_a_id); intListPosB := RankList.AddObject(str_team_b_id, RankDataB); end else RankDataB := (RankList.Objects[RankList.IndexOf(str_team_b_id)] as TRankData); //punkte, gewonnen, verloren, unentschieden sammeln if (int_result_a > int_result_b) then //team a hat gewonnen begin RankDataA.Points := RankDataA.Points + int_pts_g; RankDataB.Points := RankDataB.Points + int_pts_vl; RankDataA.Won := RankDataA.Won + 1; RankDataB.Loss := RankDataB.Loss + 1; end else if (int_result_a < int_result_b) then //team b hat gewonnen begin RankDataB.Points := RankDataB.Points + int_pts_g; RankDataA.Points := RankDataA.Points + int_pts_vl; RankDataB.Won := RankDataB.Won + 1; RankDataA.Loss := RankDataA.Loss + 1; end else // bleibt unentschieden begin RankDataB.Points := RankDataB.Points + int_pts_u; RankDataA.Points := RankDataA.Points + int_pts_u; RankDataB.Draw := RankDataB.Draw + 1; RankDataA.Draw := RankDataA.Draw + 1; end; //tore geschossen, erhalten und auswärts RankDataA.Goals := RankDataA.Goals + int_result_a; RankDataB.Goals := RankDataB.Goals + int_result_b; RankDataA.ReGoals := RankDataA.ReGoals + int_result_b; RankDataB.ReGoals := RankDataB.ReGoals + int_result_a; RankDataB.Goals_Away := RankDataB.Goals_Away + int_result_b; //tore gegen die andere mannschaft (wichtig für direkten vergleich) //hierzu fehlt mir leider noch eine idee zum übersetzen!!! //$results[$team_a_id]['gegen_team'][$team_b_id]['tore_heim'] = $result_a; //$results[$team_b_id]['gegen_team'][$team_a_id]['tore_ausw'] = $result_b; //spiele RankDataA.Games := RankDataA.Games + 1; RankDataB.Games := RankDataB.Games + 1; Next; end; end; //debugging der datenlage TabString.Clear; for i := 0 to RankList.Count -1 do begin TabString.Add(RankList.Strings[i]+' - Team: '+ (RankList.Objects[i] as TRankData).TeamName + ' - Points: ' + inttostr((RankList.Objects[i] as TRankData).Points) + ' - Goals: ' + inttostr((RankList.Objects[i] as TRankData).Goals) + ' - RGoals: ' + inttostr((RankList.Objects[i] as TRankData).ReGoals) + ' - Games: ' + inttostr((RankList.Objects[i] as TRankData).Games)); end; ShowMessage(TabString.Text); end; TeamID - Teamname - Punkte - erzielte Tore - erhaltene Tore - gespielte Spiele 2383 - Team: Switzerland - Points: 6 - Goals: 4 - RGoals: 1 - Games: 2 2384 - Team: Slovakia - Points: 3 - Goals: 3 - RGoals: 4 - Games: 2 2381 - Team: Germany - Points: 4 - Goals: 6 - RGoals: 6 - Games: 2 2382 - Team: Canada - Points: 2 - Goals: 4 - RGoals: 6 - Games: 2 Wie in der Ausgabe auffällt ist da noch nichts sortiert. In der Stringliste selbst stehen nur die TeamId´s. In den dazugehörenden Objekten sind dann die Daten vorrätig. Dann würde ich noch gern wissen, ob es reicht einfach nur die Stringliste zu "Clearen", um auch die daran hängenden Objekte freizugeben!?? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:56 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz