Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add helper functions to check arrays that conform to various constraints #40

Open
delphidabbler opened this issue Jan 10, 2025 · 3 comments
Assignees
Labels
considering Issue is currently under consideration enhancement New feature or request

Comments

@delphidabbler
Copy link
Owner

delphidabbler commented Jan 10, 2025

The following helper functions check arrays for all <0, ≤0, 0, ≥0, >0 and ≠0 entries:

// Check if all elements of a non-empty array are zero 
function ArrayIsZero(const A: array of Extended): Boolean;
begin
  Assert(Length(A) > 0);
  Result := False;
  for var Elem in A do
    if not IsZero(Elem) then
      Exit;
  Result := True;
end;

// Check if all elements of a non-empty array are <> 0 
function ArrayIsNonZero(const A: array of Extended): Boolean;
begin
  Assert(Length(A) > 0);
  Result := False;
  for var Elem in A do
    if IsZero(Elem) then
      Exit;
  Result := True;
end;

// Check if all elements of a non-empty array are > 0 
function ArrayIsPositive(const A: array of Extended): Boolean;
begin
  Assert(Length(A) > 0);
  Result := False;
  for var Elem in A do
    if Sign(Elem) <> PositiveValue then
      Exit;
  Result := True;
end;

// Check if all elements of a non-empty array are < 0 
function ArrayIsNegative(const A: array of Extended): Boolean;
begin
  Assert(Length(A) > 0);
  Result := False;
  for var Elem in A do
    if Sign(Elem) <> NegativeValue then
      Exit;
  Result := True;
end;

// Check if all elements of a non-empty array are <= 0 
function ArrayIsNonPositive(const A: array of Extended): Boolean;
begin
  Assert(Length(A) > 0);
  Result := False;
  for var Elem in A do
    if Sign(Elem) = PositiveValue then
      Exit;
  Result := True;
end;

// Check if all elements of a non-empty array are >= 0 
function ArrayIsNonNegative(const A: array of Extended): Boolean;
begin
  Assert(Length(A) > 0);
  Result := False;
  for var Elem in A do
    if Sign(Elem) = NegativeValue then
      Exit;
  Result := True;
end;

This issue was extracted from issue #16

@delphidabbler delphidabbler self-assigned this Jan 10, 2025
@delphidabbler delphidabbler added enhancement New feature or request considering Issue is currently under consideration labels Jan 10, 2025
@github-project-automation github-project-automation bot moved this to Considering in Code Snippets Jan 10, 2025
@delphidabbler
Copy link
Owner Author

The proposed routines can be generalised / replaced with the more general function which is inspired by the JavaScript Array.every() function:

function ArrayEvery(const A: array of Extended; const Constraint: TPredicate<Extended>): Boolean;
begin
  Assert(Length(A) > 0); // could possibly return False in case of empty array
  Result := False;
  for var Elem in A do
    if not Constraint(Elem) then
      Exit;
  Result := True;
end;

The possible overloads are obvious.

@delphidabbler
Copy link
Owner Author

delphidabbler commented Jan 10, 2025

Further drawing from JavaScript we could have, in addition to the above comment, the JavaScript.some() inspired:

function ArraySome(const A: array of Extended; const Constraint: TPredicate<Extended>): Boolean;
begin
  Assert(Length(A) > 0); // could possibly return False in case of empty array
  Result := True;
  for var Elem in A do
    if Constraint(Elem) then
      Exit;
  Result := False;
end;

@delphidabbler
Copy link
Owner Author

delphidabbler commented Jan 10, 2025

This comment is now addressed by issue #43


Generalising ArrayEvery and ArraySome discussed above, we could add generic versions to the TArrayUtils<T> record:

type
  TArrayUtils<T> = record
  public
    ...
    class function Every<T>(const A: array of T; 
      const Constraint: TPredicate<T>): Boolean; static;
    class function Some<T>(const A: array of T; 
      const Constraint: TPredicate<T>): Boolean; static;
    ...
  end;

...

class function TArrayUtils.Every<T>(const A: array of T; 
  const Constraint: TPredicate<T>: Boolean;
begin
  Assert(Length(A) > 0); // could possibly return False in case of empty array
  Result := False;
  for var Elem in A do
    if not Constraint(Elem) then
      Exit;
  Result := True;
end;

class function TArrayUtils.Some<T>(const A: array of T; 
  const Constraint: TPredicate<T>): Boolean;
begin
  Assert(Length(A) > 0); // could possibly return False in case of empty array
  Result := True;
  for var Elem in A do
    if Constraint(Elem) then
      Exit;
  Result := False;
end;

...

Example:

var EveryALT0 := TArrayUtils.Every<Integer>(
  [0,-1,2,-3,4], 
  function (Elem: Integer): Boolean
  begin
    Result := Elem < 0; 
  end
);
var SomeAGTE0 := TArrayUtils.Some<Integer>(
  [0,-1,2,-3,4], 
  function (Elem: Integer): Boolean
  begin
    Result := Elem >= 0; 
  end
);

Here EveryALT0 gets set to False (Not every element of the array is < 0) and SomeAGTE0 is True (at least one element of the array is >= 0).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
considering Issue is currently under consideration enhancement New feature or request
Projects
Status: Considering
Development

No branches or pull requests

1 participant