Skip to content

Latest commit

 

History

History
123 lines (91 loc) · 3.85 KB

File metadata and controls

123 lines (91 loc) · 3.85 KB

Some<T> class method

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 Some<T>(const A: array of T;
  const AConstraint: TConstraint<T>): Boolean;
  overload; static;

class function Some<T>(const A: array of T;
  const AConstraint: TConstraintEx<T>): Boolean;
  overload; static;

Description

Checks if at least one element of a non-empty array satisfies 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):

    • AElem - The current array element to be tested.
    • AIndex - The index of AElem in A. (TConstraintEx<T> only.)
    • A - Reference to the array containing AElem. (TConstraintEx<T> only.)

    Returns:

    • True if AElem satisfies the required criteria or False otherwise.

Returns:

  • True if AConstraint returns True for one or more elements of A, or False otherwise.

Precondition:

  • A must not be empty. An EAssertionFailed exception is raised otherwise.

Note

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.

Examples

Example #1

The first example checks if some elements of an integer array are ≥ 4. We only need the simple TConstraint<T> overload.

procedure Some_Eg1;
var
  A, B, C: TArray<Integer>;
  Constraint: TArrayUtils.TConstraint<Integer>;
begin
  A := TArray<Integer>.Create(1, 2, 3, 4, 5, 3);
  B := TArray<Integer>.Create(4, 5, 6);
  C := TArray<Integer>.Create(1, 2, 1);
  Constraint := function (const AElem: Integer): Boolean
    begin
      Result := AElem >= 4;
    end;
  Assert(TArrayUtils.Some<Integer>(A, Constraint) = True);
  Assert(TArrayUtils.Some<Integer>(B, Constraint) = True);
  Assert(TArrayUtils.Some<Integer>(C, Constraint) = False);
end;

Example #2

The second example checks that the distance between some 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 Some<T> is required.

procedure Some_Eg2;
var
  Constraint: TArrayUtils.TConstraintEx<Integer>;
  A, B, C, D: TArray<Integer>;
begin
  Constraint := function (const AElem: Integer; const AIndex: Integer;
    const A: array of Integer): Boolean
    var
      Distance: Integer;
    begin
      // True iff distance between 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(False);
      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(0, 2, 4);
  D := TArray<Integer>.Create(42);
  Assert(TArrayUtils.Some<Integer>(A, Constraint) = True);
  Assert(TArrayUtils.Some<Integer>(B, Constraint) = True);
  Assert(TArrayUtils.Some<Integer>(C, Constraint) = False);
  Assert(TArrayUtils.Some<Integer>(D, Constraint) = True);
end;

See Also