![]() |
Slicing for Delphi™
Liste der Anhänge anzeigen (Anzahl: 2)
Moin moin!
Der eine oder andere von euch kennt sicher aus anderen Programmiersprachen das Slicing-Konzept. Für die, die es nicht kennen, hier eine kurze Einführung: Dass man auf ein Listenelement mittels Liste[Index] zugreifen kann, ist sicher nichts neues. Das dumme daran: Man bekommt immer nur ein Element zurück. Und hier kommt das Slicing ins Spiel, welches derartige Zugriffe quasi exponentiell nützlicher macht. Die Grundlegende Syntax ist Liste[StartIndex:StopIndex]. Und eigentlich ist das schon ziemlich selbsterklärend, hier ein paar Beipsiele, was man damit so machen kann:
Code:
Nun, wems bis jetzt noch nicht gedämmert ist: Soetwas gibt es in Delphi leider nicht :(
Liste[0:4] 0tes - 5tes Element
Liste[3:4] 4tes - 5tes Element Liste[:5] 0tes - 6tes Element Liste[3:] 4tes - letztes Element Liste[1:-1] zweites - vorletztes Element u.v.m. Ich bin grade dabei mir zu überlgen, inwieweit man das in Delphi integrieren könnte. Herausgekommen ist dabei bis jetzt eine Beispielimplementation TSlicedStringList:
Delphi-Quellcode:
Das neue an ihr: sowas geht
unit SlicedStringList;
interface uses Classes; type TSlicedStringList = class(TStringList) private function GetStrings(Slice: string): TStrings; //procedure SetStrings(Slice: string; const Value: TStrings); public property Strings[Index: Integer]: string read Get write Put; default; property Strings[Slice: string]: TStrings read GetStrings; default; end; implementation uses SysUtils, Dialogs; { TExtStringList } type TIntArray = array of Integer; function GetIntArrayFromSlice(const Slice: string; const Max: Integer): TIntArray; var strStartPos, strStopPos: string; StartPos, StopPos, i: Integer; begin strStartPos := Copy(Slice, 1, Pos(':', Slice) - 1); strStopPos := Copy(Slice, Pos(':', Slice) + 1, Length(Slice)); case Length(strStartPos) of 0: StartPos := 0; else StartPos := StrToInt(strStartPos); end; case Length(strStopPos) of 0: StopPos := Max; else StopPos := StrToInt(strStopPos); end; if StartPos < 0 then StartPos := Max + StartPos; if StopPos < 0 then StopPos := Max + StopPos; SetLength(Result, StopPos - StartPos + 1); for i := StartPos to StopPos do begin Result[i - StartPos] := i; end; end; function TSlicedStringList.GetStrings(Slice: string): TStrings; var i: Integer; begin Result := TStringList.Create; case Pos(':', Slice) of 0: Result.Add(Strings[StrToInt(Slice)]); else begin for i in GetIntArrayFromSlice(Slice, Count - 1) do Result.Add(Strings[i]); end; end; end; //procedure TSlicedStringList.SetStrings(Slice: string; const Value: TStrings); //begin // //end; end.
Delphi-Quellcode:
Im Anhang findet ihr eine kleine Demo-Anwendung dazu, nix großes, soll nur das Prinzip verdeutlichen und enthält KEINE Fehlerabfragen, derartige 'Bugreports' sind also überflüssig ;)
lst := StringList['1:4'];
Die spannende Frage ist nun: Was haltet ihr davon? Nützlich? Fürn Popo? Unbedingt weiterentwicklen? Und wenn weiterentwickeln, was wären die Konventionen, die ihr bevorzugegen würdet? Soll [-1] Das letzte oder das vorletzte Element liefern? (Beides ergibt Sinn). Soll der EndIndex im Ergebnis enthalten sein oder nicht (beide Versionen gibt es in anderen Sprachen). Fällt euch eine bessere Möglichkeit ein, als das ganze per string zu übergeben (was nicht sehr nützlich ist, aber es ist der einizge Weg, der mir spontan eingefallen ist)? Nuja, her mit euren Ideen und Anregungen :) |
Re: Slicing for Delphi™
Zitat:
Delphi-Quellcode:
TSlicedStringList = class
private function GetSlice(From, To: integer): TStrings; ... public property Slices[From,To: integer]: TStrings read GetSlice; ... end; ...
Delphi-Quellcode:
lst := SlicedStringList.Slices[1,4];
lst.free; |
Re: Slicing for Delphi™
Zitat:
[-1] Wäre das letzte Element, [0, -1] würde was anderes bedeuten, man müsste dafür also [-1, -1] übergeben. Auch irgendwie blöd :| |
Re: Slicing for Delphi™
Zitat:
EDIT: ![]() Siehe mein Beitrag MfG |
Re: Slicing for Delphi™
Interessant!
Ich würde das mit dem ![]() Dazu leitet man von TStrings ab und muss dann natürlich alle virtuellen (und abstrakten) Methoden überschreiben. Dabei leitet man die Methoden nur auf das TStrings-Objekt weiter, dass im Konstruktor übergeben wurde.
Delphi-Quellcode:
TSlicedStrings = class(TStrings)
private FStrings : TStrings; function GetSlice(const Range: string): TStrings; //procedure SetStrings(Slice: string; const Value: TStrings); public constructor Create(AStrings:TStrings); function Add(const S: string): Integer; override; property Slice[const Range: string]: TStrings read GetStrings; property Slice[fromIdx,toIdx:Integer]:TStrings; // 2. Variante end; constructor TSlicedStrings.Create(AStrings:TStrings); begin inherited Create; FStrings := AStrings; end; function TSlicedStrings.Add(const S: string): Integer; override; begin Result := FStrings.Add(S); // einfach auf internes Objekt umleiten end; function TSlicedStrings.GetSlice(const Range: string): TStrings; var i,j : Integer; begin Result := TStringList.Create; case Pos(':', Range) of 0: begin j := StrToInt(Range); Result.AddObject(Strings[j], Objects[j]); end else begin for i in GetIntArrayFromSlice(Range, Count - 1) do Result.AddObject(Strings[i], Objects[i]); end; end; end; |
Re: Slicing for Delphi™
Zitat:
|
Re: Slicing for Delphi™
Lustig. Der Nachteil des String-Parametersi ist die etwas sehr umständliche Verwurstung von Variablen. I.A. benötige ich nicht das 2. bis 5. Element, sondern das i.te bis j.te (bzw. N Elemente ab Position I). Ich müsste mir also den Deskriptorstring mittels IntToStr oder Format zusammenbasteln. Das ist irgendwie blöd.
Delphi-Quellcode:
Übersichlich geht anders.
MySlicedStringList := StringList[Format('%d:%d',[I,N])];
|
Re: Slicing for Delphi™
Zitat:
Zitat:
Zitat:
Zitat:
|
Re: Slicing for Delphi™
xD
Um etwas klarzustellen -> meinst du mit [0:-1] ~ [0:Anzahl der Rechten Elemente - 1] ? Falls nein, dann war mal mein Beitrag wieder voll daneben :roll: MfG |
Re: Slicing for Delphi™
bei Arrays kann man auch Copy nutzen ... ok, ohne das "von rechts"
Delphi-Quellcode:
ansonsten gibt's 2 Möglichkeiten für die Parameter:
var a: Array of Double;
a := Copy(a, 5, 9);
Delphi-Quellcode:
public
property Slices[From: Integer; To: Integer = MinInt]: TStrings read GetSlice; // if To = MinInt then {to=from} // else {from,to}
Delphi-Quellcode:
public
property Slices[From, To: Integer]: TStrings read GetSlice2; Default; property Slices[To: Integer]: TStrings read GetSlice1; Default; ... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:51 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