gpt4 book ai didi

delphi - 如何实现具有 IsFirst 和 IsLast 函数的枚举器?

转载 作者:行者123 更新时间:2023-12-03 15:47:46 24 4
gpt4 key购买 nike

我对所有集合都使用 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.

CurrentIsFirst 可以使用本地 bool 值来实现,一旦第一个值通过,该 bool 值就会重置。

但是我不知道实现 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;

这是基本算法,但您可以将其放入 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;

关于delphi - 如何实现具有 IsFirst 和 IsLast 函数的枚举器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37569882/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com