[fpc-devel] for-in-index loop
Sven Barth
pascaldragon at googlemail.com
Fri Jan 25 19:17:53 CET 2013
On 25.01.2013 17:18, Alexander Klenin wrote:
> With this in mind, consider a user who wants to iterate over the
> following array:
>
> var
> a: array [1..5] of Integer = (1, 2, 9, 4, 5);
>
> In my proposal, he should write:
> var
> v, i: Integer;
> begin
> for a in a index i do
> Writeln(i, ' ', v);
> end.
>
> In your proposal, he should write (suppose GIter is a unit
> implementing the generic array iterator):
> uses
> GIter;
> type
> TArrayIntIterator = specialize TArrayIterator<Integer>;
> i: TArrayIntIterator.TElem;
> begin
> for i in TArrayIntIterator.Create(a) do
> Writeln(i.Index + Low(a), ' ', i.Value);
> end.
One could also do an alternative (though currently not with arrays, but
with type helper support even that would be possible...):
=== code begin ===
type
// let's assume we extend fgl.TFPGMap a bit
TFPGMap<Key, Data> = class
public type
TIteratorProc = procedure(const aKey: Key; const aValue: Data);
public
procedure Iterate(aProc: TIteratorProc);
end;
// skipping the implementation of TFPGMap.Iterate...
// somewhere else
procedure Iterator(const aKey: String; const aValue: TObject);
begin
Writeln(aKey, ' => ', aValue.ClassName);
end;
type
TFPGMapStringTObject = specialize TFPGMap<String, TObject>;
var
map: TFPGMapStringTObject;
begin
// set up map
map.Iterate(@Iterator);
end;
=== code end ===
With support for anonymous functions (and changing TIteratorProc to
"reference to procedure(...)") it even becomes:
=== code begin ===
begin
map.Iterate(procedure(const aKey: String; const aValue: TObject)
begin
Writeln(aKey, ' => ', aValue.ClassName);
end;
);
end;
=== code end ===
And for a given array type and type helper support you can do the following:
=== code begin ===
var
t: TLongIntArray; // there exists a helper for this type that
implements a Iterate function
begin
// set up t
t.Iterate(@Iterator);
// or
t.Iterate(procedure(const aIndex, aData: LongInt)
begin
Writeln(aIndex, ' => ', aData);
end;
);
end;
=== code end ===
In all cases the iterate function would iterate the "container" type
with a fitting algorithm and just call the given function with the
necessary data. This is in my opinion a rather flexible way of dealing
with iteration (by adding additional arguments you could for example
influence the iteration direction).
Regards,
Sven
More information about the fpc-devel
mailing list