Re: "Array" mit Strings als Indizes (Zuordnungstab
Zitat:
Zitat:
Zitat:
|
Re: "Array" mit Strings als Indizes (Zuordnungstab
Zitat:
Aus dem selben Grund finde ich auch Ableiten hier geschickter als einen Wrapper: Man verliert nicht den Zugriff auf die alten Funktionen, sondern erreicht deine neuen nur zusätzlich und bleibt kompatibel zu Prozeduren, die die Vorfahren erwarten. |
Re: "Array" mit Strings als Indizes (Zuordnungstab
Zitat:
Ja, im Allgemeinen Fall wäre eine Ableitung besser. Eben mit den einfachereren Funktionen als Zusatz. |
Re: "Array" mit Strings als Indizes (Zuordnungstab
Das gleichlautende Einträge beim Abschalten kollidieren ist natürlich wahr, den Fall müsste man in der Tat berücksichtigen und überlegen, welcher in der Liste bleiben darf und ob dies ggf. irgendwie kenntlich gemacht wird (Exception, Message).
|
Re: "Array" mit Strings als Indizes (Zuordnungstab
Kennst du schon die Array-Properties?
Damit kann man die Sache sehr elegant lösen:
Delphi-Quellcode:
Ein bekanntes Array-Property ist z.B. Pixel[] der Klasse TCanvas.
TEasyObjectManager = class(TObject)
private function GetValues(const Name: string): TObject; procedure SetValues(const Name: string; Value: TObject); public ... // das ist ein Array-Property // interessant ist, das der Datentyp des Index auch string oder ein beliebiger anderer Datentyp sein darf // auch mehrdimensionale Indizes sind möglich property Values[const Name:string]:TObject read GetValues write SetValue; end; Die Deklaration sieht ungefähr so aus:
Delphi-Quellcode:
Wenn man unsicher ist, wie die Get- und Set-Methoden aussehen sollen, dann schreibt
property Pixel[x,y:Integer]:TColor read GetPixel write SetPixel;
das Array-Property einfach hin und drückt dann Strg+Shift+C und die IDE erzeugt dann automatisch die richtigen Methodenkörper. |
Re: "Array" mit Strings als Indizes (Zuordnungstab
:shock: Das ist ja was tolles! Vielen Dank für den Hinweis, da komm ich ja dem PHP-Fealing noch näher. Werde ich später gleich mal ausprobieren.
|
Re: "Array" mit Strings als Indizes (Zuordnungstab
Hallo.
Ich bin jetzt zum entschluss gekommen, folgende Dinge zu machen: 1. Klasse von TStringList ableiten anstelle eines Wrappers 2. Exception werfen, wenn Eintrag nicht existiert anstelle nil zu liefern. Bezüglich (1) möchte ich aber folgende Funktionweise: Es soll eine Exception geworfen werden, wenn durch das Ändern von Case-Sensitive Einträge miteinander "verschmelzen" (bzw. genau genommen danach nicht mehr durch ObjectByString[str] nicht mehr zugreifbar sind). Dazu habe ich eine kleine Frage bevor ich meinen Code hier veröffentliche: Wie prüfe ich performant, ob bei einer CaseSensitive=False Änderung Einträge "verschmelzen" werden? Gruß blackdrake |
Re: "Array" mit Strings als Indizes (Zuordnungstab
Liste der Anhänge anzeigen (Anzahl: 1)
OK, hier nun mein fertiger Code:
Delphi-Quellcode:
Die Exceptions bei "Verschmelzung" von Einträgen habe ich doch nicht gemacht, da ein solches Verhalten nicht nur durch Case-Sensitive entstehen kann, sondern auch, wenn man einfach zwei Einträge mit identischen Strings hinzufügt. Wenn man aber Konsequent nur mit ObjectByString[] arbeitet, kommt es zu keiner Überdeckung.
unit ObjMan;
interface uses SysUtils, IniFiles; type TObjectManager = class(THashedStringList) private function GetObjectByString(const Str: String): TObject; procedure SetObjectByString(const Str: String; const Value: TObject); function GetStringByObject(const Obj: TObject): String; procedure SetStringByObject(const Obj: TObject; const Value: String); public function StringExists(const Str: String): boolean; function ObjectExists(const Obj: TObject): boolean; function DeleteString(const Str: String): boolean; property ObjectByString[const Str: string]: TObject read GetObjectByString write SetObjectByString; property StringByObject[const Obj: TObject]: String read GetStringByObject write SetStringByObject; end; EStringNotFound = class(Exception); EObjectNotFound = class(Exception); resourcestring E_STRING_NOT_FOUND = 'The string "%s" was not found in the list.'; E_OBJECT_NOT_FOUND = 'Object was not found in the list.'; implementation { TObjectManager } function TObjectManager.GetObjectByString(const Str: string): TObject; var i: integer; begin i := IndexOf(Str); if i <> -1 then result := Objects[i] else raise EStringNotFound.CreateFmt(E_STRING_NOT_FOUND, [Str]); end; procedure TObjectManager.SetObjectByString(const Str: string; const Value: TObject); var i: integer; begin i := IndexOf(Str); if i <> -1 then Objects[i] := Value else AddObject(Str, Value); end; function TObjectManager.StringExists(const Str: string): boolean; begin result := IndexOf(Str) <> -1; end; function TObjectManager.ObjectExists(const Obj: TObject): boolean; begin result := IndexOfObject(Obj) <> -1; end; function TObjectManager.DeleteString(const Str: string): boolean; var i: integer; begin i := IndexOf(Str); result := i <> -1; if result then Delete(i); end; function TObjectManager.GetStringByObject(const Obj: TObject): String; var i: integer; begin i := IndexOfObject(Obj); if i <> -1 then result := Strings[i] else raise EObjectNotFound.Create(E_OBJECT_NOT_FOUND); end; procedure TObjectManager.SetStringByObject(const Obj: TObject; const Value: String); var i: integer; begin i := IndexOfObject(Obj); if i <> -1 then Strings[i] := Value else AddObject(Value, Obj); end; end. Man beachte bitte das dynamische Verhalten von SetStringByObject() und SetObjectByString(). Diese fügen einen neuen Eintrag hinzu, wenn man auf ein unbekanntes Element schreibend zugreift. Gruß blackdrake |
Re: "Array" mit Strings als Indizes (Zuordnungstab
ich spiel auch mal ein bissl mit :angel2: ... nja, zumindestens das "Array" funktioniert schonmal :stupid:
Delphi-Quellcode:
Uses Types, SysConst, SysUtils;
Type TMyType = Integer; TMyStringIndizeInnerArray = Array of Record Name: String; Data: TMyType; End; TMyStringIndizeArray = Record Private _A: TMyStringIndizeInnerArray; Procedure SetData(Const Name: String; Const Data: TMyType); Function GetData(Const Name: String): TMyType; Procedure SetDataI( Index: Integer; Const Data: TMyType); Function GetDataI( Index: Integer): TMyType; Function GetName ( Index: Integer): String; Public Class Operator Implicit(Const A: TMyStringIndizeInnerArray): TMyStringIndizeArray; Class Operator Implicit(Const Rec: TMyStringIndizeArray): TMyStringIndizeInnerArray; Property Data[Const Name: String]: TMyType Read GetData Write SetData; Default; Property Data[ Index: Integer]: TMyType Read GetDataI Write SetDataI; Default; Property Name[ Index: Integer]: String Read GetName; End; Procedure TMyStringIndizeArray.SetData(Const Name: String; Const Data: TMyType); Var i: Integer; Begin i := 0; While (i < Length(_A)) and (_A[i].Name <> Name) do Inc(i); If (i >= Length(_A)) Then Begin SetLength(_A, i + 1); _A[i].Name := Name; End; _A[i].Data := Data; End; Function TMyStringIndizeArray.GetData(Const Name: String): TMyType; Var i: Integer; Begin i := High(_A); While _A[i].Name <> Name do Dec(i); Result := GetDataI(i); End; Procedure TMyStringIndizeArray.SetDataI(Index: Integer; Const Data: TMyType); Begin If (Index >= 0) and (Index < Length(_A)) Then _A[Index].Data := Data Else Raise ERangeError.CreateRes(@SRangeError); End; Function TMyStringIndizeArray.GetDataI(Index: Integer): TMyType; Begin If (Index >= 0) and (Index < Length(_A)) Then Result := _A[Index].Data Else Raise ERangeError.CreateRes(@SRangeError); End; Function TMyStringIndizeArray.GetName(Index: Integer): String; Begin If (Index >= 0) and (Index < Length(_A)) Then Begin If _A[Index].Name <> '' Then Result := _A[Index].Name Else Result := IntToStr(Index); End Else Raise ERangeError.CreateRes(@SRangeError); End; Class Operator TMyStringIndizeArray.Implicit(Const A: TMyStringIndizeInnerArray): TMyStringIndizeArray; Begin Result._A := A; End; Class Operator TMyStringIndizeArray.Implicit(Const Rec: TMyStringIndizeArray): TMyStringIndizeInnerArray; Begin Result := Rec._A; End; procedure TForm1.FormCreate(Sender: TObject); Var A: TMyStringIndizeArray; Begin //SetLength(A, 5); // geht leider doch nicht ... blöder Var-Parameter -.-° A['himi'] := 0815; If A['himi'] = A[0] Then ; If Length(A) = 1 Then ; // aber warum geht das auch nicht? o.O End; |
Re: "Array" mit Strings als Indizes (Zuordnungstab
Sieht nett aus :thumb:
[OT] Ich benutze in so einer Situation aber eher Dictionary<TKey, TValue> bzw. im speziellen dann Dictionary<String, int> :stupid: SCNR :mrgreen: [/OT] |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:42 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