Einzelnen Beitrag anzeigen

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