uses
System.SysUtils, System.Generics.Collections;
type
TIteratorWrapper<T> = class
private
FEnumerable: TEnumerable<T>;
public
constructor Create(Iterable: TEnumerable<T>);
function Map(Func: TFunc<T, T>): TIteratorWrapper<T>;
function Filter(Func: TFunc<T, Boolean>): TIteratorWrapper<T>;
function Take(N: Integer): TIteratorWrapper<T>;
function ToArray: TArray<T>;
function GetEnumerator: TEnumerator<T>;
end;
constructor TIteratorWrapper<T>.Create(Iterable: TEnumerable<T>);
begin
FEnumerable := Iterable;
end;
function TIteratorWrapper<T>.Map(Func: TFunc<T, T>): TIteratorWrapper<T>;
var
Enumerator: TEnumerator<T>;
begin
Result := TIteratorWrapper<T>.Create(
TEnumerable<T>.Create(
function: TEnumerator<T>
begin
Enumerator := FEnumerable.GetEnumerator;
Result := TEnumerator<T>.Create(
function: Boolean
begin
Result := Enumerator.MoveNext;
if Result then
Enumerator.Current := Func(Enumerator.Current);
end
);
end
)
);
end;
function TIteratorWrapper<T>.Filter(Func: TFunc<T, Boolean>): TIteratorWrapper<T>;
var
Enumerator: TEnumerator<T>;
begin
Result := TIteratorWrapper<T>.Create(
TEnumerable<T>.Create(
function: TEnumerator<T>
begin
Enumerator := FEnumerable.GetEnumerator;
Result := TEnumerator<T>.Create(
function: Boolean
begin
while Enumerator.MoveNext do
begin
if Func(Enumerator.Current) then
Exit(True);
end;
Result := False;
end
);
end
)
);
end;
function TIteratorWrapper<T>.Take(N: Integer): TIteratorWrapper<T>;
var
Count: Integer;
Enumerator: TEnumerator<T>;
begin
Count := 0;
Result := TIteratorWrapper<T>.Create(
TEnumerable<T>.Create(
function: TEnumerator<T>
begin
Enumerator := FEnumerable.GetEnumerator;
Result := TEnumerator<T>.Create(
function: Boolean
begin
if Count < N then
begin
Result := Enumerator.MoveNext;
Inc(Count);
end
else
Result := False;
end
);
end
)
);
end;
function TIteratorWrapper<T>.ToArray: TArray<T>;
var
Enumerator: TEnumerator<T>;
List: TList<T>;
begin
List := TList<T>.Create;
try
Enumerator := FEnumerable.GetEnumerator;
while Enumerator.MoveNext do
List.Add(Enumerator.Current);
Result := List.ToArray;
finally
List.Free;
end;
end;
function TIteratorWrapper<T>.GetEnumerator: TEnumerator<T>;
begin
Result := FEnumerable.GetEnumerator;
end;
{ Helper functie }
function From<T>(Iterable: TEnumerable<T>): TIteratorWrapper<T>;
begin
Result := TIteratorWrapper<T>.Create(Iterable);
end;
procedure TestLazyIterator;
var
Numbers: TArray<Integer>;
Result: TArray<Integer>;
begin
Numbers := TArray<Integer>.Create(1, 2, 3, 4, 5);
Result := From<Integer>(TArray<Integer>.Create(Numbers))
.Map(
function(X: Integer): Integer
begin
Result := X * 2;
end)
.Filter(
function(X: Integer): Boolean
begin
Result := X > 5;
end)
.Take(2)
.ToArray;
WriteLn('Resultaat: ', String.Join(', ', Result)); // Resultaat: 6, 8
end;
begin
TestLazyIterator;
end.
897500cookie-checkDelphi / Pascal IteratorWrapper