2016-06-01 16 views
3

Ich verwende Spring4D für alle Sammlungen.Wie implementiere ich einen Enumerator mit IsFirst- und IsLast-Funktionen?

Jetzt gibt es eine Situation, in der ich wissen muss, ob der aktuelle Wert des Enumerators der erste (der einfach ist) oder der letzte (der schwer ist) in der Auflistung ist.

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 könnte eine lokale Boolesche implementiert werden, die, sobald der erste Wert zurückgesetzt wird, bestanden hat.

Allerdings kenne ich keine einfache Möglichkeit CurrentIsLast zu implementieren.

Es sollte in der Lage sein, faule Sammlungen zu verarbeiten, da sie zu viele Werte enthalten können, um in den Speicher zu passen.

Wie kann ich eine solche CurrentIsLast Funktion implementieren?

+0

Ich frage mich immer noch, was Sie mit dem Wissen erreichen wollen, wenn ein Element das erste oder letzte ist und es nicht ganz anders gelöst werden kann. –

+0

Wir verwenden es für eine etwas ungewöhnliche Form eines [Control Break] (https://en.wikipedia.org/wiki/Control_break). –

+0

Wie gesagt, könnte es eine andere Möglichkeit geben, dies zu tun - zum Beispiel in dem Wikipedia-Artikel, mit dem Sie verlinkt haben, spricht von einer Gruppierung, die mit TEnumerable.GroupBy gemacht werden kann. –

Antwort

6

Verwenden Sie einfach ein Flag während der Iteration:

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; 

Dies ist der grundlegende Algorithmus aber Sie können das für IEnumerator<T> in Dekorateur setzen IsFirst/IsLast zur Verfügung zu stellen - Sie müssen nur das aktuelle Element Puffer und schauen eine voraus, um zu sehen, ob die aktuelle die letzte ist.