AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Mehrdimensionaler Array wie in PHP möglich?

Ein Thema von torud · begonnen am 18. Nov 2010 · letzter Beitrag vom 20. Nov 2010
Antwort Antwort
torud

Registriert seit: 26. Jul 2002
Ort: Sachsen
1.198 Beiträge
 
Delphi XE5 Professional
 
#1

Mehrdimensionaler Array wie in PHP möglich?

  Alt 18. Nov 2010, 13:06
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[$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;
$results ist ein mehrdimensionales Array
$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.
Danke
Tom
  Mit Zitat antworten Zitat
Benutzerbild von ChrisE
ChrisE

Registriert seit: 15. Feb 2006
Ort: Hechingen
504 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#2

AW: Mehrdimensionaler Array wie in PHP möglich?

  Alt 18. Nov 2010, 13:17
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
Christian E.
Es gibt 10 Arten von Menschen, die die Binär lesen können und die die es nicht können

Delphi programming rules
  Mit Zitat antworten Zitat
Hansa

Registriert seit: 9. Jun 2002
Ort: Saarland
7.554 Beiträge
 
Delphi 8 Professional
 
#3

AW: Mehrdimensionaler Array wie in PHP möglich?

  Alt 18. Nov 2010, 13:19
array [1..2,1..3,1..10] of ... Das wäre jetzt dreidimensional.
Gruß
Hansa
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.542 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Mehrdimensionaler Array wie in PHP möglich?

  Alt 18. Nov 2010, 13:29
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;
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.149 Beiträge
 
Delphi 12 Athens
 
#5

AW: Mehrdimensionaler Array wie in PHP möglich?

  Alt 18. Nov 2010, 15:12
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 Hier im Forum suchenassoziatives, Hier im Forum suchenassoziativ oder Hier im Forum suchenAssocArray
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
Benutzerbild von implementation
implementation

Registriert seit: 5. Mai 2008
940 Beiträge
 
FreePascal / Lazarus
 
#6

AW: Mehrdimensionaler Array wie in PHP möglich?

  Alt 18. Nov 2010, 16:06
Oder ein Dictionary / HashTable
  Mit Zitat antworten Zitat
torud

Registriert seit: 26. Jul 2002
Ort: Sachsen
1.198 Beiträge
 
Delphi XE5 Professional
 
#7

AW: Mehrdimensionaler Array wie in PHP möglich?

  Alt 20. Nov 2010, 23:22
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 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;
Hier noch das Ausgabeergebnis meiner ShowMessage, welches inhaltlich korrekt aber leider noch nicht sortiert ist:
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!??
Danke
Tom
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:50 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz