Thema: Delphi Slicing for Delphi™

Einzelnen Beitrag anzeigen

Benutzerbild von Meflin
Meflin

Registriert seit: 21. Aug 2003
4.856 Beiträge
 
#1

Slicing for Delphi™

  Alt 24. Mär 2009, 17:05
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:
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.
Nun, wems bis jetzt noch nicht gedämmert ist: Soetwas gibt es in Delphi leider nicht

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:
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.
Das neue an ihr: sowas geht
lst := StringList['1:4']; 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




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
Miniaturansicht angehängter Grafiken
minidemo_299.jpg  
Angehängte Dateien
Dateityp: exe slicing_126.exe (442,5 KB, 11x aufgerufen)
  Mit Zitat antworten Zitat