From faee789507bda5631c20fdfeec34e4f28a6fcb2d Mon Sep 17 00:00:00 2001 From: michael Date: Sat, 2 Nov 2019 15:08:27 +0000 Subject: [PATCH] * Add some functional methods to TStrings git-svn-id: trunk@43365 - --- rtl/objpas/classes/classesh.inc | 25 ++++ rtl/objpas/classes/stringl.inc | 211 +++++++++++++++++++++++++++++++- 2 files changed, 235 insertions(+), 1 deletion(-) diff --git a/rtl/objpas/classes/classesh.inc b/rtl/objpas/classes/classesh.inc index 4d5d7b0efe..7f36806f13 100644 --- a/rtl/objpas/classes/classesh.inc +++ b/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 } diff --git a/rtl/objpas/classes/stringl.inc b/rtl/objpas/classes/stringl.inc index 508edce4bb..dd36e4d682 100644 --- a/rtl/objpas/classes/stringl.inc +++ b/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 (Result0) 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);