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
TConstraint<T> = reference to function (const AElem: T): Boolean;
TConstraintEx<T> = reference to function (const AElem: T;
const AIndex: Integer; const AArray: array of T): Boolean;
class function Every<T>(const A: array of T;
const AConstraint: TConstraint<T>): Boolean;
overload; static;
class function Every<T>(const A: array of T;
const AConstraint: TConstraintEx<T>): Boolean;
overload; static;
Checks if all elements of a non-empty array satisfy a given constraint.
Parameters:
A - Array to be checked.
AConstraint - Constraint function called for each element of A. Returns True
if the element meets the required criteria or False
otherwise. AConstraint must be a function of type TConstraint<T> or TConstraintEx<T>.
Parameter(s):
Returns:
True
if AElem satisfies the required criteria or False
otherwise.Returns:
True
if AConstraint returns True
for all elements of A, or False
otherwise.Precondition:
The TConstraint<T> overload is all you need for most purposes. However there are cases where it is useful to have access to the whole array or the element’s index within the array, which is the reason the TConstraintEx<T> overload is provided.
The first example checks if all elements of an integer array are ≥ 4
. We only need the simple TConstraint<T> overload.
procedure Every_Eg1;
var
A, B: TArray<Integer>;
Constraint: TArrayUtils.TConstraint<Integer>;
begin
A := TArray<Integer>.Create(1, 2, 3, 4, 5, 3);
B := TArray<Integer>.Create(4, 5, 6);
Constraint := function (const AElem: Integer): Boolean
begin
Result := AElem >= 4;
end;
Assert(TArrayUtils.Every<Integer>(A, Constraint) = False);
Assert(TArrayUtils.Every<Integer>(B, Constraint) = True);
end;
The second example checks that the distance between all adjacent integers in an array is no more than one. To do this we need to be able to access the array element before a given element. Therefore the TConstraintEx<T> overload of Every<T> is required.
procedure Every_Eg2;
var
Constraint: TArrayUtils.TConstraintEx<Integer>;
A, B, C: TArray<Integer>;
begin
Constraint := function (const AElem: Integer; const AIndex: Integer;
const A: array of Integer): Boolean
var
Distance: Integer;
begin
// True iff distance betwent element and prior element <=1
// Assume that single element arrays meet the criteria
if Length(A) = 1 then
Exit(True);
Assert(A[AIndex] = AElem);
if AIndex = 0 then
Exit(True);
Distance := Abs(A[AIndex] - A[AIndex - 1]);
Result := Distance <= 1;
end;
A := TArray<Integer>.Create(0, 1, 0, 1, 2, 1, 2, 1, 0);
B := TArray<Integer>.Create(0, 1, 2, 0, 1, 2);
C := TArray<Integer>.Create(42);
Assert(TArrayUtils.Every<Integer>(A, Constraint) = True);
Assert(TArrayUtils.Every<Integer>(B, Constraint) = False);
Assert(TArrayUtils.Every<Integer>(C, Constraint) = True);
end;