2016-06-02 3 views
2

Ich bin mir bewusst, dass in Delphi, wenn Sie die Verwendung des Index-Operator erlauben wollen, [], Sie müssen etwas tun, wie,Index Operator Eigenschaft auf 2D-Array in Delphi

property Item[index: integer]: integer read GetData; default; 

Wie würde ein geht über ein mehrdimensionales Array in Delphi Implementierung, so dass es die Verwendung von so etwas wie erlaubt:

matrix := TMatrix<integer>.Create(3,3); 
matrix[0][2] := 5; 
WriteLn(matrix[0][2]); 

Antwort

6

Sie nicht [][] so verwenden können. Sie können jedoch mehrere Indizes in einer einzigen Eigenschaft deklarieren statt, zB:

type 
    TMatrix<T> = class 
    private 
    function GetData(index1, index2: Integer): T; 
    procedure SetData(index1, index2: Integer; value: T); 
    public 
    constructor Create(dim1, dim2: Integer); 
    property Item[index1, index2: Integer]: T read GetData write SetData; default; 
    end; 

Dann können Sie dies tun:

matrix := TMatrix<integer>.Create(3,3); 
matrix[0, 2] := 5; 
WriteLn(matrix[0, 2]); 
+0

Ah! Danke, ich bekomme immer noch das Gefühl dieser Sprache und es sind kleine Fragen wie diese, die mich wirklich stolpern lassen. – Zulukas

1

Wenn Sie möchten, können Sie [][] verwenden, um Elemente zuzugreifen. Wenn Ihr Typ ein Array ist (zweidimensionale oder gezackte Dynamik), wird diese Methode des Zugriffs auf die Elemente in die Sprache übernommen. Für einen benutzerdefinierten Typ müssen Sie ihn implementieren.

Es gibt keine Möglichkeit, [][] in einem einzigen Schritt in einem benutzerdefinierten Typ zu implementieren. Was Sie tun müssen, ist den Prozess in zwei separate Teile zu brechen. Der erste Teil besteht darin, [] zu implementieren, um eine Zeile Ihrer Matrix zurückzugeben. Implementieren Sie dann [] in dieser Zeile, um ein Element zurückzugeben. Hier ein Beispiel:

type 
    TMatrix<T> = class 
    public 
    type 
     TRow = record 
     private 
     FMatrix: TMatrix<T>; 
     FRowIndex: Integer; 
     function GetItem(ColIndex: Integer): T; inline; 
     procedure SetItem(ColIndex: Integer; const Value: T); inline; 
     public 
     property Items[ColIndex: Integer]: T read GetItem write SetItem; default; 
     end; 
    private 
    FData: TArray<TArray<T>>; 
    function GetRow(RowIndex: Integer): TRow; inline; 
    public 
    constructor Create(RowCount, ColCount: Integer); 
    property Rows[RowIndex: Integer]: TRow read GetRow; default; 
    end; 

{ TMatrix<T>.TRow } 

function TMatrix<T>.TRow.GetItem(ColIndex: Integer): T; 
begin 
    Result := FMatrix.FData[FRowIndex, ColIndex]; 
end; 

procedure TMatrix<T>.TRow.SetItem(ColIndex: Integer; const Value: T); 
begin 
    FMatrix.FData[FRowIndex, ColIndex] := Value; 
end; 

{ TMatrix<T> } 

constructor TMatrix<T>.Create(RowCount, ColCount: Integer); 
begin 
    inherited Create; 
    SetLength(FData, RowCount, ColCount); 
end; 

function TMatrix<T>.GetRow(RowIndex: Integer): TRow; 
begin 
    Result.FMatrix := Self; 
    Result.FRowIndex := RowIndex; 
end; 

jedoch gezeigt hat, dass dies möglich ist, würde ich vorschlagen, dass mehr idiomatische ist ein array property mit zwei Indizes zu verwenden. Das würde bedeuten, dass Sie auf die Matrix mit M[Row,Col] eher als M[Row][Col] zugreifen würden. Dieses spezielle Idiom (M[Row,Col]) ist nicht in allen Sprachen zu finden, so dass Sie es vielleicht nicht kennen. dass die Unterstützung könnte wie folgt aussehen:

type 
    TMatrix<T> = class 
    public 
    type 
     TRow = record 
     private 
     FMatrix: TMatrix<T>; 
     FRowIndex: Integer; 
     function GetItem(ColIndex: Integer): T; inline; 
     procedure SetItem(ColIndex: Integer; const Value: T); inline; 
     public 
     property Items[ColIndex: Integer]: T read GetItem write SetItem; default; 
     end; 
    private 
    FData: TArray<TArray<T>>; 
    function GetRow(RowIndex: Integer): TRow; inline; 
    function GetItem(RowIndex, ColIndex: Integer): T; inline; 
    procedure SetItem(RowIndex, ColIndex: Integer; const Value: T); inline; 
    public 
    constructor Create(RowCount, ColCount: Integer); 
    property Rows[RowIndex: Integer]: TRow read GetRow; 
    property Items[RowIndex, ColIndex: Integer]: T read GetItem write SetItem; default; 
    end; 

{ TMatrix<T>.TRow } 

function TMatrix<T>.TRow.GetItem(ColIndex: Integer): T; 
begin 
    Result := FMatrix.FData[FRowIndex, ColIndex]; 
end; 

procedure TMatrix<T>.TRow.SetItem(ColIndex: Integer; const Value: T); 
begin 
    FMatrix.FData[FRowIndex, ColIndex] := Value; 
end; 

{ TMatrix<T> } 

constructor TMatrix<T>.Create(RowCount, ColCount: Integer); 
begin 
    inherited Create; 
    SetLength(FData, RowCount, ColCount); 
end; 

function TMatrix<T>.GetRow(RowIndex: Integer): TRow; 
begin 
    Result.FMatrix := Self; 
    Result.FRowIndex := RowIndex; 
end; 

function TMatrix<T>.GetItem(RowIndex, ColIndex: Integer): T; 
begin 
    Result := FData[RowIndex, ColIndex]; 
end; 

procedure TMatrix<T>.SetItem(RowIndex, ColIndex: Integer; const Value: T); 
begin 
    FData[RowIndex, ColIndex] := Value; 
end; 

Beachten Sie, dass in dieser Version, die wir gewählt haben, um Items die Standardeigenschaft zu machen sein. Wenn Sie auf eine Zeile zugreifen möchten, müssen Sie die Rows-Eigenschaft explizit benennen: M.Rows[RowIndex].