This is a new site that's currently running on alpha code. There are going to be bugs. If you discover any, please report them on the site's issues page (GitHub account required). Thanks.
Warning: Many URLs are going to change. Refer to the README file to discover which library project's documentation has been completed.
Project: Array Utilities Unit
Unit: DelphiDabbler.Lib.ArrayUtils
Record: TArrayUtils
Applies to: ~>0.1
type
TReducer<T> = reference to function (const AAccumulator, ACurrent: T): T;
TReducerEx<T> = reference to function (const AAccumulator, ACurrent: T;
const AIndex: Integer; const AArray: array of T): T;
class function Reduce<T>(const A: array of T;
const AReducer: TReducer<T>): T;
overload; static;
class function Reduce<T>(const A: array of T; const AReducer: TReducer<T>;
const AInitialValue: T): T;
overload; static;
class function Reduce<T>(const A: array of T; const AReducer: TReducerEx<T>;
const AInitialValue: T): T;
overload; static;
Reduces the elements of an array to a single value of the same type as the array elements.
Parameters:
A - The array whose elements are to be reduced.
AReducer - Callback function executed for each element in the array that is used to calculate the reduced value. AReducer must be a function of type TReducer<T> or TReducerEx<T>.
Parameter(s):
0
if AInitialValue is specified, otherwise the value is 1
. (TReducerEx<T> only.)Returns:
AInitialValue - An optional value to which AAccumulator is initialised the first time that AReducer is called.
If AInitialValue is specified then AReducer starts executing with AAccumulator set to AInitialValue and ACurrent is set to A[0] . If A is empty then AReducer is never called.
If AInitialValue is not specified then AReducer starts executing with AAccumulator set to A[0] and ACurrent is set to A[1]. If A has only one element then AReducer is never called.
Returns:
The single value that results from running AReducer over the elements of A.
If AInitialValue is specified and A is empty then AInitialValue is returned.
If AInitialValue is not specified and A has just one element then A[0] returned.
Precondition:
The first example uses the 1st overload of Reduce<T>, which requires a non-empty array. The example computes the sum of a given integer array.
procedure Reduce_SingleType_Eg1;
var
A: TArray<Integer>;
SumCallback: TArrayUtils.TReducer<Integer>;
begin
SumCallback := function (const AAccumulator, ACurrent: Integer): Integer
begin
Result := ACurrent + AAccumulator;
end;
A := TArray<Integer>.Create(1, 3, 5, 7, 9);
Assert(TArrayUtils.Reduce<Integer>(A, SumCallback) = 25);
end;
The second example exercises the 2nd Reduce<T> overload, using the AInitialValue parameter and the simple TReducer<T> callback function. The code demonstrates how to cumulatively add multiple arrays.
procedure Reduce_SingleType_Eg2;
var
A, B: TArray<Integer>;
SumCallback: TArrayUtils.TReducer<Integer>;
RunningTotal: Integer;
begin
SumCallback := function (const AAccumulator, ACurrent: Integer): Integer
begin
Result := ACurrent + AAccumulator;
end;
A := TArray<Integer>.Create(1, 3, 5, 7, 9); // sum = 25
B := TArray<Integer>.Create(2, 4, 6, 8, 10); // sum = 30
RunningTotal := 0;
RunningTotal := TArrayUtils.Reduce<Integer>(A, SumCallback, RunningTotal);
Assert(RunningTotal = 25);
RunningTotal := TArrayUtils.Reduce<Integer>(B, SumCallback, RunningTotal);
Assert(RunningTotal = 55);
end;
The final example sums the absolute distances between adjacent elements of an integer array. It uses the 3rd Reduce<T> overload, using the AInitialValue and the more complex TReducerEx<T> callback function.
procedure Reduce_SingleType_Eg3;
var
SumDistancesReducer: TArrayUtils.TReducerEx<Integer>;
A: TArray<Integer>;
begin
// Adds the absolute distances between adjacent elements of an integer array
SumDistancesReducer := function (const AAccumulator, ACurrent: Integer;
const AIndex: Integer; const AArray: array of Integer): Integer
var
Distance: Integer;
begin
Result := AAccumulator;
if AIndex = 0 then
Exit;
Distance := Abs(AArray[AIndex] - AArray[AIndex - 1]);
Result := Result + Distance;
end;
A := TArray<Integer>.Create(3, 6, 3, 8, 3, 2);
Assert(TArrayUtils.Reduce<Integer>(A, SumDistancesReducer, 0) = 17);
end;