Jen*_*off 3 delphi enumerator spring4d delphi-xe7
我正在使用Spring4D进行所有收藏.
现在有一种情况我必须知道枚举器的当前值是集合中的第一个(很容易)还是最后一个(很难).
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
Spring.Collections;
var
Enumerable: IEnumerable<Integer>;
Enumerator: IEnumerator<Integer>;
begin
Enumerable := TEnumerable.Query<Integer>(TArray<Integer>.Create(1, 2, 3, 4, 5)
) as IEnumerable<Integer>;
Enumerator := Enumerable.GetEnumerator;
while Enumerator.MoveNext do
begin
WriteLn('Value = ', Enumerator.Current);
WriteLn('First in collection? ', Enumerator.CurrentIsFirst);
WriteLn('Last in collection? ', Enumerator.CurrentIsLast);
end;
ReadLn;
end.
Run Code Online (Sandbox Code Playgroud)
CurrentIsFirst 可以使用本地布尔值实现,该布尔值在第一个值通过后重置.
但是,我不知道一种简单的实施方法CurrentIsLast.
它应该能够处理延迟集合,因为它们可能包含太多值以适应内存.
我该如何实现这样的CurrentIsLast功能?
只需在迭代期间使用一个标志:
if Enumerator.MoveNext then
begin
flag := True;
repeat
WriteLn('Value = ', Enumerator.Current);
WriteLn('First in collection? ', flag);
flag := not Enumerator.MoveNext;
WriteLn('Last in collection? ', flag);
until flag;
end;
Run Code Online (Sandbox Code Playgroud)
这是基本的算法,但你可以把它放到装饰器中IEnumerator<T>来提供IsFirst/ IsLast- 你只需要缓冲当前元素并提前查看当前元素是否是最后一个.
type
IEnumeratorEx<T> = interface(IEnumerator<T>)
function IsFirst: Boolean;
function IsLast: Boolean;
end;
TEnumeratorState = (Initial, First, Only, Running, Last, Finished);
TEnumeratorEx<T> = class(TEnumeratorBase<T>, IEnumeratorEx<T>)
private
fSource: IEnumerator<T>;
fCurrent: T;
fState: TEnumeratorState;
function IsFirst: Boolean;
function IsLast: Boolean;
protected
function GetCurrent: T; override;
function MoveNext: Boolean; override;
public
constructor Create(const source: IEnumerator<T>);
end;
constructor TEnumeratorEx<T>.Create(const source: IEnumerator<T>);
begin
inherited Create;
fSource := source;
end;
function TEnumeratorEx<T>.GetCurrent: T;
begin
Result := fCurrent;
end;
function TEnumeratorEx<T>.IsFirst: Boolean;
begin
Result := fState in [First, Only];
end;
function TEnumeratorEx<T>.IsLast: Boolean;
begin
Result := fState in [Only, Last];
end;
function TEnumeratorEx<T>.MoveNext: Boolean;
begin
case fState of
Initial:
if fSource.MoveNext then
fState := First
else
fState := Finished;
First:
fState := Running;
Only, Last:
fState := Finished;
end;
Result := fState <> Finished;
if Result then
begin
fCurrent := fSource.Current;
if not fSource.MoveNext then
Inc(fState);
end;
end;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
314 次 |
| 最近记录: |