Browse Source

* Add some functional methods to TStrings

git-svn-id: trunk@43365 -
michael 5 years ago
parent
commit
faee789507
2 changed files with 235 additions and 1 deletions
  1. 25 0
      rtl/objpas/classes/classesh.inc
  2. 210 1
      rtl/objpas/classes/stringl.inc

+ 25 - 0
rtl/objpas/classes/classesh.inc

@@ -602,6 +602,12 @@ type
   end;
 
 { TStrings class }
+  TStringsFilterMethod = function(const s: string): boolean of object;
+  TStringsReduceMethod = function(const s1, s2: string): string of object;
+  TStringsMapMethod = function(const s: string): string of object;
+  TStringsForEachMethodExObj = procedure(const CurrentValue: string; const index: integer; Obj : TObject) of object;
+  TStringsForEachMethodEx = procedure(const CurrentValue: string; const index: integer) of object;
+  TStringsForEachMethod = procedure(const CurrentValue: string) of object;
   TMissingNameValueSeparatorAction = (mnvaValue,mnvaName,mnvaEmpty,mnvaError);
   TMissingNameValueSeparatorActions = set of TMissingNameValueSeparatorAction;
 
@@ -700,25 +706,43 @@ type
     function Equals(TheStrings: TStrings): Boolean; overload;
     procedure Exchange(Index1, Index2: Integer); virtual;
     function  ExtractName(Const S:String):String;
+    Procedure Filter(aFilter: TStringsFilterMethod; aList : TStrings);
+    Function Filter(aFilter: TStringsFilterMethod) :  TStrings;
+    Procedure Fill(const aValue : String; aStart,aEnd : Integer);
+    procedure ForEach(aCallback: TStringsForeachMethod);
+    procedure ForEach(aCallback: TStringsForeachMethodEx);
+    procedure ForEach(aCallback: TStringsForeachMethodExObj);
     function GetEnumerator: TStringsEnumerator;
     procedure GetNameValue(Index : Integer; Out AName,AValue : String);
     function GetText: PChar; virtual;
     function IndexOf(const S: string): Integer; virtual;
+    function IndexOf(const S: string; aStart : Integer): Integer; virtual;
     function IndexOfName(const Name: string): Integer; virtual;
     function IndexOfObject(AObject: TObject): Integer; virtual;
     procedure Insert(Index: Integer; const S: string); virtual; abstract;
     procedure InsertObject(Index: Integer; const S: string; AObject: TObject);
+    function LastIndexOf(const S: string; aStart : Integer): Integer; virtual;
+    function LastIndexOf(const S: string): Integer;
     procedure LoadFromFile(const FileName: string); overload; virtual;
     procedure LoadFromFile(const FileName: string; IgnoreEncoding : Boolean);
     procedure LoadFromFile(const FileName: string; AEncoding: TEncoding); overload; virtual;
     procedure LoadFromStream(Stream: TStream); overload; virtual;
     procedure LoadFromStream(Stream: TStream; IgnoreEncoding : Boolean); overload;
     procedure LoadFromStream(Stream: TStream; AEncoding: TEncoding); overload; virtual;
+    Procedure Map(aMap: TStringsMapMethod; aList : TStrings);
+    Function Map(aMap: TStringsMapMethod) : TStrings;
     procedure Move(CurIndex, NewIndex: Integer); virtual;
+    Function Pop : String;
+    function Reduce(aReduceMethod: TStringsReduceMethod; const startingValue: string): string;
+    Function Reverse : TStrings;
+    Procedure Reverse(aList : TStrings);
     procedure SaveToFile(const FileName: string); overload; virtual;
     procedure SaveToFile(const FileName: string; AEncoding: TEncoding); overload; virtual;
     procedure SaveToStream(Stream: TStream); overload; virtual;
     procedure SaveToStream(Stream: TStream; AEncoding: TEncoding); overload; virtual;
+    function Shift : String;
+    Procedure Slice(fromIndex: integer; aList : TStrings);
+    Function Slice(fromIndex: integer) : TStrings;
     procedure SetText(TheText: PChar); virtual;
     property AlwaysQuote: Boolean read FAlwaysQuote write FAlwaysQuote;
     property Capacity: Integer read GetCapacity write SetCapacity;
@@ -746,6 +770,7 @@ type
     property Values[const Name: string]: string read GetValue write SetValue;
     property WriteBOM: Boolean read FWriteBOM write FWriteBOM;
   end;
+  TStringsClass = Class of TStrings;
 
 { TStringList class }
 

+ 210 - 1
rtl/objpas/classes/stringl.inc

@@ -284,6 +284,159 @@ begin
     Result:='';
 end;
 
+
+procedure TStrings.Filter(aFilter: TStringsFilterMethod; aList: TStrings);
+
+var
+  S : string;
+
+begin
+  for S in self do
+    if aFilter(S) then
+      aList.Add(S);
+end;
+
+
+procedure TStrings.ForEach(aCallback: TStringsForeachMethod);
+
+var
+  S : String;
+
+begin
+  for S in self do
+    aCallBack(S);
+end;
+
+
+procedure TStrings.ForEach(aCallback: TStringsForeachMethodEx);
+
+var
+  i: integer;
+
+begin
+  for i:=0 to Count-1 do
+    aCallBack(Strings[i],i);
+end;
+
+
+procedure TStrings.ForEach(aCallback: TStringsForeachMethodExObj);
+
+var
+  i: integer;
+
+begin
+  for i:=0 to Count-1 do
+    aCallback(Strings[i],i,Objects[i]);
+end;
+
+
+function TStrings.Filter(aFilter: TStringsFilterMethod): TStrings;
+
+begin
+  Result:=TStringsClass(Self.ClassType).Create;
+  try
+    Filter(aFilter,Result);
+  except
+    FreeAndNil(Result);
+    Raise;
+  end;
+end;
+
+procedure TStrings.Fill(const aValue: String; aStart, aEnd: Integer);
+var
+  i: integer;
+begin
+  if aEnd<0 then
+    aEnd:=Self.Count+aEnd;
+  if aEnd>=Count then
+    aEnd:=Count-1;
+  for i:=aStart to aEnd do
+    Strings[i]:=aValue;
+end;
+
+
+Procedure TStrings.Map(aMap: TStringsMapMethod; aList : TStrings);
+
+Var
+  S : String;
+
+begin
+  For S in self do
+    aList.Add(aMap(S));
+end;
+
+
+Function TStrings.Map(aMap: TStringsMapMethod) : TStrings;
+
+begin
+  Result:=TStringsClass(Self.ClassType).Create;
+  try
+    Map(aMap,Result);
+  except
+    FreeAndNil(Result);
+    Raise;
+  end;
+end;
+
+
+function TStrings.Reduce(aReduceMethod: TStringsReduceMethod; const startingValue: string): string;
+
+var
+  S : String;
+
+begin
+  Result:=startingValue;
+  for S in self do
+    Result:=aReduceMethod(Result, S);
+end;
+
+
+Function TStrings.Reverse : TStrings;
+
+begin
+  Result:=TStringsClass(Self.ClassType).Create;
+  try
+    Reverse(Result);
+  except
+    FreeAndNil(Result);
+    Raise;
+  end;
+end;
+
+
+Procedure TStrings.Reverse(aList : TStrings);
+
+Var
+  I : Integer;
+
+begin
+  for I:=Count-1 downto 0 do
+    aList.Add(Strings[i]);
+end;
+
+
+Procedure TStrings.Slice(fromIndex: integer; aList : TStrings);
+
+var
+  i: integer;
+
+begin
+  for i:=fromIndex to Count-1 do
+    aList.Add(Self[i]);
+end;
+
+Function TStrings.Slice(fromIndex: integer) :  TStrings;
+
+begin
+  Result:=TStringsClass(Self.ClassType).Create;
+  try
+    Slice(FromIndex,Result);
+  except
+    FreeAndNil(Result);
+    Raise;
+  end;
+end;
+
 function TStrings.GetName(Index: Integer): string;
 
 Var
@@ -1018,6 +1171,19 @@ begin
   if Result=Count then Result:=-1;
 end;
 
+function TStrings.IndexOf(const S: string; aStart: Integer): Integer;
+begin
+  if aStart<0 then
+    begin
+    aStart:=Count+aStart;
+    if aStart<0 then
+      aStart:=0;
+    end;
+  Result:=aStart;
+  While (Result<Count) and (DoCompareText(Strings[Result],S)<>0) do Result:=Result+1;
+  if Result=Count then Result:=-1;
+end;
+
 
 Function TStrings.IndexOfName(const Name: string): Integer;
 Var
@@ -1054,7 +1220,26 @@ begin
   Objects[Index]:=AObject;
 end;
 
+function TStrings.LastIndexOf(const S: string): Integer;
 
+begin
+  Result:=LastIndexOf(S,Count-1);
+end;
+
+function TStrings.LastIndexOf(const S: string; aStart : Integer): Integer;
+begin
+  if aStart<0 then
+    begin
+    aStart:=Count+aStart;
+    if aStart<0 then
+      aStart:=0;
+    end;
+  Result:=aStart;
+  if Result>=Count-1 then
+    Result:=Count-1;
+  While (Result>=0) and (DoCompareText(Strings[Result],S)<>0) do
+    Result:=Result-1;
+end;
 
 Procedure TStrings.LoadFromFile(const FileName: string);
 
@@ -1064,7 +1249,7 @@ end;
 
 Procedure TStrings.LoadFromFile(const FileName: string; IgnoreEncoding : Boolean);
 Var
-        TheStream : TFileStream;
+  TheStream : TFileStream;
 begin
   TheStream:=TFileStream.Create(FileName,fmOpenRead or fmShareDenyWrite);
   try
@@ -1196,7 +1381,31 @@ begin
     end;
 end;
 
+function TStrings.Pop: string;
 
+var
+  C : Integer;
+
+begin
+  Result:='';
+  C:=Count-1;
+  if (C>=0) then
+    begin
+    Result:=Strings[C];
+    Delete(C);
+    end;
+end;
+
+function TStrings.Shift: String;
+
+begin
+  Result:='';
+  if (Count > 0) then
+    begin
+    Result:=Strings[0];
+    Delete(0);
+    end;
+end;
 
 Procedure TStrings.SaveToFile(const FileName: string);