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