Added HigherOrder.Map<T1,T2> with some overloads
Some checks are pending
TOC Generator / TOC Generator (push) Waiting to run

This commit is contained in:
Daniele Teti 2024-11-03 17:21:58 +01:00
parent beef11fba9
commit 8503c77b41
3 changed files with 162 additions and 10 deletions

View File

@ -47,7 +47,7 @@ object MainForm: TMainForm
object btnMapAddStars: TButton object btnMapAddStars: TButton
Left = 8 Left = 8
Top = 27 Top = 27
Width = 95 Width = 74
Height = 30 Height = 30
Caption = 'Add Stars' Caption = 'Add Stars'
TabOrder = 0 TabOrder = 0
@ -61,7 +61,6 @@ object MainForm: TMainForm
Anchors = [akLeft, akTop, akBottom] Anchors = [akLeft, akTop, akBottom]
ItemHeight = 13 ItemHeight = 13
TabOrder = 1 TabOrder = 1
ExplicitHeight = 219
end end
object btnFilterBetween: TButton object btnFilterBetween: TButton
Left = 380 Left = 380
@ -81,7 +80,6 @@ object MainForm: TMainForm
Anchors = [akLeft, akTop, akBottom] Anchors = [akLeft, akTop, akBottom]
ItemHeight = 13 ItemHeight = 13
TabOrder = 3 TabOrder = 3
ExplicitHeight = 219
end end
object btnReduceSum: TButton object btnReduceSum: TButton
Left = 194 Left = 194
@ -100,7 +98,6 @@ object MainForm: TMainForm
Anchors = [akLeft, akTop, akBottom] Anchors = [akLeft, akTop, akBottom]
ItemHeight = 13 ItemHeight = 13
TabOrder = 5 TabOrder = 5
ExplicitHeight = 219
end end
object btnReduceMin: TButton object btnReduceMin: TButton
Left = 194 Left = 194
@ -152,7 +149,7 @@ object MainForm: TMainForm
object btnMapCapitalize: TButton object btnMapCapitalize: TButton
Left = 8 Left = 8
Top = 63 Top = 63
Width = 95 Width = 74
Height = 30 Height = 30
Caption = 'Capitalize' Caption = 'Capitalize'
TabOrder = 11 TabOrder = 11
@ -175,7 +172,6 @@ object MainForm: TMainForm
Anchors = [akLeft, akTop, akBottom] Anchors = [akLeft, akTop, akBottom]
ItemHeight = 13 ItemHeight = 13
TabOrder = 13 TabOrder = 13
ExplicitHeight = 219
end end
object btnForEachWithException: TButton object btnForEachWithException: TButton
Left = 566 Left = 566
@ -186,4 +182,22 @@ object MainForm: TMainForm
TabOrder = 14 TabOrder = 14
OnClick = btnForEachWithExceptionClick OnClick = btnForEachWithExceptionClick
end end
object btnMap2: TButton
Left = 88
Top = 27
Width = 100
Height = 30
Caption = 'Map Enumerable'
TabOrder = 15
OnClick = btnMap2Click
end
object btnMap2Array: TButton
Left = 88
Top = 63
Width = 100
Height = 30
Caption = 'Map Array'
TabOrder = 16
OnClick = btnMap2ArrayClick
end
end end

View File

@ -51,6 +51,8 @@ type
btnJustLoop: TButton; btnJustLoop: TButton;
lbForEach: TListBox; lbForEach: TListBox;
btnForEachWithException: TButton; btnForEachWithException: TButton;
btnMap2: TButton;
btnMap2Array: TButton;
procedure btnMapAddStarsClick(Sender: TObject); procedure btnMapAddStarsClick(Sender: TObject);
procedure btnReduceSumClick(Sender: TObject); procedure btnReduceSumClick(Sender: TObject);
procedure btnFilterBetwenClick(Sender: TObject); procedure btnFilterBetwenClick(Sender: TObject);
@ -62,6 +64,8 @@ type
procedure btnMapCapitalizeClick(Sender: TObject); procedure btnMapCapitalizeClick(Sender: TObject);
procedure btnJustLoopClick(Sender: TObject); procedure btnJustLoopClick(Sender: TObject);
procedure btnForEachWithExceptionClick(Sender: TObject); procedure btnForEachWithExceptionClick(Sender: TObject);
procedure btnMap2Click(Sender: TObject);
procedure btnMap2ArrayClick(Sender: TObject);
private private
procedure FillList(Data: TArray<String>; AStrings: TStrings); overload; procedure FillList(Data: TArray<String>; AStrings: TStrings); overload;
procedure FillList(Data: TArray<Integer>; AStrings: TStrings); overload; procedure FillList(Data: TArray<Integer>; AStrings: TStrings); overload;
@ -74,6 +78,9 @@ var
implementation implementation
uses
System.Generics.Collections;
{$R *.dfm} {$R *.dfm}
@ -170,6 +177,57 @@ begin
end); end);
end; end;
procedure TMainForm.btnMap2ArrayClick(Sender: TObject);
begin
lbMap.Clear;
var lInput: TArray<Integer>;
SetLength(lInput, 10);
for var I := 1 to Length(lInput) do
begin
lInput[I-1] := I * 10;
end;
var lListOfStr := HigherOrder.Map<Integer, String>(
lInput, function(const Item: Integer): String
begin
Result := '**' + Item.ToString;
end);
try
lbMap.Items.AddStrings(lListOfStr.ToArray);
finally
lListOfStr.Free;
end;
end;
procedure TMainForm.btnMap2Click(Sender: TObject);
begin
lbMap.Clear;
var lList := TList<TButton>.Create;
try
for var lControl in Self.GetControls([ceftEnabled]) do
begin
if lControl is TButton then
begin
lList.Add(TButton(lControl));
end;
end;
var lListOfStr := HigherOrder.Map<TButton, String>(
lList, function(const Item: TButton): String
begin
Result := String(Item.Caption).ToUpper;
end);
try
lbMap.Items.AddStrings(lListOfStr.ToArray);
finally
lListOfStr.Free;
end;
finally
lList.Free;
end;
end;
procedure TMainForm.btnMapAddStarsClick(Sender: TObject); procedure TMainForm.btnMapAddStarsClick(Sender: TObject);
var var
InputData, OutputData: TArray<string>; InputData, OutputData: TArray<string>;

View File

@ -30,7 +30,8 @@ interface
uses uses
MVCFramework.Serializer.Commons, JsonDataObjects, MVCFramework.Serializer.Commons, JsonDataObjects,
MVCFramework.DuckTyping, System.Classes, System.SysUtils; MVCFramework.DuckTyping, System.Classes, System.SysUtils,
System.Generics.Collections;
type type
EHOError = class(Exception) EHOError = class(Exception)
@ -54,19 +55,27 @@ type
end; end;
TMapClosure<T> = reference to function(const Item: T): T; TMapClosure<T> = reference to function(const Item: T): T;
TMapClosure2<T1,T2> = reference to function(const Item: T1): T2;
TForEachClosure<T> = reference to procedure(const Item: T); TForEachClosure<T> = reference to procedure(const Item: T);
TMapReduceClosure<T> = reference to function(const Left: T; const Right: T): T; TMapReduceClosure<T> = reference to function(const Left: T; const Right: T): T;
TPredicateClosure<T> = reference to function(const Item: T): Boolean; TPredicateClosure<T> = reference to function(const Item: T): Boolean;
HigherOrder = class sealed HigherOrder = class sealed
public
class function Map<T>(const InputArray: TArray<T>; class function Map<T>(const InputArray: TArray<T>;
const MapClosure: TMapClosure<T>): TArray<T>; const MapClosure: TMapClosure<T>): TArray<T>; overload;
class function Map<T1,T2>(const List: TEnumerable<T1>;
const MapClosure: TMapClosure2<T1, T2>): TList<T2>; overload;
class function Map<T1,T2>(const InputArray: TArray<T1>;
const MapClosure: TMapClosure2<T1, T2>): TList<T2>; overload;
class function Reduce<T>(const InputArray: TArray<T>; class function Reduce<T>(const InputArray: TArray<T>;
const ReduceFunction: TMapReduceClosure<T>; InitValue: T): T; const ReduceFunction: TMapReduceClosure<T>; InitValue: T): T;
class function Filter<T>(const InputArray: TArray<T>; class function Filter<T>(const InputArray: TArray<T>;
const FilterFunction: TPredicateClosure<T>): TArray<T>; const FilterFunction: TPredicateClosure<T>): TArray<T>;
class procedure ForEach<T>(const InputArray: TArray<T>; class procedure ForEach<T>(const InputArray: TArray<T>;
const ForEachClosure: TForEachClosure<T>); const ForEachClosure: TForEachClosure<T>); overload;
class procedure ForEach<T>(const Enumerable: TEnumerable<T>;
const ForEachClosure: TForEachClosure<T>); overload;
end; end;
function NewJSONSerializer: IMVCJSONSerializer; function NewJSONSerializer: IMVCJSONSerializer;
@ -87,7 +96,6 @@ uses
IdHashMessageDigest, IdHashMessageDigest,
IdHashSHA, IdHashSHA,
{$ENDIF} {$ENDIF}
System.Generics.Collections,
MVCFramework.Serializer.JsonDataObjects, MVCFramework.Serializer.JsonDataObjects,
MVCFramework.Commons, MVCFramework.Commons,
System.TypInfo; System.TypInfo;
@ -241,6 +249,78 @@ begin
end; end;
end; end;
class procedure HigherOrder.ForEach<T>(const Enumerable: TEnumerable<T>; const ForEachClosure: TForEachClosure<T>);
var
lIdx: Integer;
lItem: T;
begin
lIdx := 0;
try
for lItem in Enumerable do
begin
ForEachClosure(lItem);
Inc(lIdx);
end;
except
on E: Exception do
begin
raise EHOForEachError.CreateFmt
('ForEach error at element %d - [Class: %s][Message: %s]',
[lIdx, E.ClassName, E.Message]);
end;
end;
end;
class function HigherOrder.Map<T1, T2>(const List: TEnumerable<T1>; const MapClosure: TMapClosure2<T1, T2>): TList<T2>;
var
lIdx: Integer;
lItem: T1;
begin
Result := nil;
lIdx := 0;
try
Result := TList<T2>.Create;
for lItem in List do
begin
Result.Add(MapClosure(lItem));
Inc(lIdx);
end;
except
on E: Exception do
begin
Result.Free;
raise EHOMapError.CreateFmt
('Map error at index %d - [Class: %s][Message: %s]',
[lIdx, E.ClassName, E.Message]);
end;
end;
end;
class function HigherOrder.Map<T1, T2>(const InputArray: TArray<T1>; const MapClosure: TMapClosure2<T1, T2>): TList<T2>;
var
lIdx: Integer;
lItem: T1;
begin
Result := nil;
lIdx := 0;
try
Result := TList<T2>.Create;
for lItem in InputArray do
begin
Result.Add(MapClosure(lItem));
Inc(lIdx);
end;
except
on E: Exception do
begin
Result.Free;
raise EHOMapError.CreateFmt
('Map error at index %d - [Class: %s][Message: %s]',
[lIdx, E.ClassName, E.Message]);
end;
end;
end;
class function HigherOrder.Map<T>(const InputArray: TArray<T>; class function HigherOrder.Map<T>(const InputArray: TArray<T>;
const MapClosure: TMapClosure<T>): TArray<T>; const MapClosure: TMapClosure<T>): TArray<T>;
var var