Skip to main content

Overview

The BI.Arrays unit provides dynamic array types and powerful helper methods for working with data in TeeBI. These arrays form the foundation of TDataItem’s storage mechanism and include extensive functionality for sorting, searching, statistical calculations, and data manipulation.

Array Types

TInt32Array
Array of Integer
Dynamic array of 32-bit integers.
var
  Numbers: TInt32Array;
begin
  Numbers.Resize(5);
  Numbers[0] := 10;
  Numbers[1] := 20;
end;
TInt64Array
Array of Int64
Dynamic array of 64-bit integers.
TSingleArray
Array of Single
Dynamic array of single-precision floating-point numbers.
TDoubleArray
Array of Double
Dynamic array of double-precision floating-point numbers (default float type).
TExtendedArray
Array of Extended
Dynamic array of extended-precision floats (10 bytes on x86, same as Double on x64).
TTextArray
Array of String
Dynamic array of strings.
TDateTimeArray
Array of TDateTime
Dynamic array of datetime values.
TBooleanArray
Array of Boolean
Dynamic array of boolean values.
TNativeIntArray
TInt32Array or TInt64Array
Platform-dependent integer array (32-bit on x86, 64-bit on x64).

Common Helper Methods

All array types provide similar helper methods through record helpers. Below are the most commonly used methods:

Array Management

Count
function
Returns the number of elements in the array.
ShowMessage('Elements: ' + IntToStr(Numbers.Count));
Resize
procedure
Changes the size of the array.
ACount
TInteger
required
New size for the array
Numbers.Resize(100); // Resize to 100 elements
Empty
procedure
Clears all elements from the array (sets length to 0).
Numbers.Empty;
Append
function
Adds a value to the end of the array.
Value
required
The value to append (type matches array type)
Returns the index of the newly added element.
var Index: Integer;
Index := Numbers.Append(42);
Copy
function
Creates a copy of the array or a portion of it.
AIndex
TInteger
Starting index for partial copy
ACount
TInteger
Number of elements to copy
var Copy1, Copy2: TInt32Array;
Copy1 := Numbers.Copy;           // Full copy
Copy2 := Numbers.Copy(10, 5);    // Copy 5 elements starting at index 10
Insert
procedure
Inserts a value at the specified position.
Index
TInteger
required
Position where to insert
Value
required
Value to insert
Numbers.Insert(5, 99); // Insert 99 at position 5
Delete
procedure
Removes one or more elements from the array.
Index
TInteger
required
Starting index to delete
ACount
TInteger
default:"1"
Number of elements to delete
Numbers.Delete(10);      // Delete element at index 10
Numbers.Delete(5, 3);    // Delete 3 elements starting at index 5
Reverse
procedure
Reverses the order of elements in the array.
Numbers.Reverse;
Swap
procedure
Swaps two elements in the array.
A
TInteger
required
First index
B
TInteger
required
Second index
Numbers.Swap(0, 5); // Swap first and sixth elements

Sorting and Searching

Sort
procedure
Sorts the array in ascending or descending order.
Ascending
Boolean
default:"True"
Sort direction
IgnoreCase
Boolean
default:"False"
For text arrays, whether to ignore case
Numbers.Sort;              // Sort ascending
Numbers.Sort(False);       // Sort descending
Text.Sort(True, True);     // Sort text case-insensitive
SortedFind
function
Performs binary search on a sorted array.
Value
required
Value to search for
Exists
Boolean
Returns True if value was found
Returns the index where the value is or should be inserted.
var
  Index: Integer;
  Found: Boolean;
begin
  Numbers.Sort; // Must be sorted first
  Index := Numbers.SortedFind(42, Found);
  if Found then
    ShowMessage('Found at index: ' + IntToStr(Index));
end;
IndexOf
function
Finds the first occurrence of a value (linear search).
Value
required
Value to search for
Returns the index of the value, or -1 if not found.
var Index: Integer;
Index := Numbers.IndexOf(42);
if Index >= 0 then
  ShowMessage('Found at: ' + IntToStr(Index));

Statistical Methods (Numeric Arrays)

Stats
function
Calculates comprehensive statistics for the array.Returns a statistics object (TInt32Stats, TDoubleStats, etc.) containing:
  • Min, Max: Minimum and maximum values
  • Mean: Average value
  • Median: Middle value
  • Mode: Most frequent value
  • Range: Difference between max and min
  • Variance: Statistical variance
  • StdDeviation: Standard deviation
  • Skewness: Distribution skewness
  • Peakedness: Distribution kurtosis
var S: TInt32Stats;
S := Numbers.Stats;
ShowMessage('Mean: ' + FloatToStr(S.Mean));
ShowMessage('Min: ' + IntToStr(S.Min));
ShowMessage('Max: ' + IntToStr(S.Max));
S.Free;
Sum
function
Calculates the sum of all values.
ShowMessage('Total: ' + FloatToStr(Numbers.Sum));
Mean
function
Calculates the average value.
ShowMessage('Average: ' + FloatToStr(Numbers.Mean));
Minimum
function
Returns the minimum value in the array.
ShowMessage('Min: ' + IntToStr(Numbers.Minimum));
Maximum
function
Returns the maximum value in the array.
ShowMessage('Max: ' + IntToStr(Numbers.Maximum));
Variance
function
Calculates variance given a mean.
Mean
TFloat
required
The mean value
var M, V: Double;
M := Numbers.Mean;
V := Numbers.Variance(M);
StdDeviation
function
Calculates standard deviation given a mean.
Mean
TFloat
required
The mean value
var M, SD: Double;
M := Numbers.Mean;
SD := Numbers.StdDeviation(M);

Usage Examples

Basic Array Operations

var
  Numbers: TInt32Array;
  I: Integer;
begin
  // Create and populate
  Numbers.Resize(5);
  Numbers[0] := 10;
  Numbers[1] := 30;
  Numbers[2] := 20;
  Numbers[3] := 50;
  Numbers[4] := 40;
  
  // Append more values
  Numbers.Append(60);
  Numbers.Append(15);
  
  ShowMessage('Count: ' + IntToStr(Numbers.Count)); // 7
  
  // Sort
  Numbers.Sort;
  
  // Display sorted
  for I := 0 to Numbers.Count - 1 do
    ShowMessage(IntToStr(Numbers[I]));
  // Shows: 10, 15, 20, 30, 40, 50, 60
end;

Statistical Analysis

var
  Values: TDoubleArray;
  Stats: TDoubleStats;
begin
  // Populate with data
  Values.Resize(100);
  for var I := 0 to 99 do
    Values[I] := Random * 100;
  
  // Calculate statistics
  Stats := Values.Stats;
  try
    ShowMessage('Count: ' + IntToStr(Values.Count));
    ShowMessage('Mean: ' + FloatToStr(Stats.Mean));
    ShowMessage('Median: ' + FloatToStr(Stats.Median));
    ShowMessage('Min: ' + FloatToStr(Stats.Min));
    ShowMessage('Max: ' + FloatToStr(Stats.Max));
    ShowMessage('Range: ' + FloatToStr(Stats.Range));
    ShowMessage('StdDev: ' + FloatToStr(Stats.StdDeviation));
  finally
    Stats.Free;
  end;
end;

Text Array Operations

var
  Names: TTextArray;
  Index: Integer;
  Found: Boolean;
begin
  // Add names
  Names.Append('Alice');
  Names.Append('Bob');
  Names.Append('Charlie');
  Names.Append('David');
  
  // Sort alphabetically (case-insensitive)
  Names.Sort(True, True);
  
  // Search
  Index := Names.SortedFind('charlie', Found, True);
  if Found then
    ShowMessage('Found at index: ' + IntToStr(Index));
  
  // Insert in sorted position
  Names.Insert(Index, 'Carlos');
end;

Copying and Filtering

var
  Source, Filtered: TInt32Array;
  I: Integer;
begin
  // Create source array
  Source.Resize(10);
  for I := 0 to 9 do
    Source[I] := I * 10; // 0, 10, 20, ..., 90
  
  // Filter: copy only values > 40
  for I := 0 to Source.Count - 1 do
    if Source[I] > 40 then
      Filtered.Append(Source[I]);
  
  ShowMessage('Filtered count: ' + IntToStr(Filtered.Count));
  // Shows: 5 (values 50, 60, 70, 80, 90)
end;

DateTime Array

var
  Dates: TDateTimeArray;
  Stats: TDateTimeStats;
begin
  // Add dates
  Dates.Append(EncodeDate(2024, 1, 15));
  Dates.Append(EncodeDate(2024, 3, 20));
  Dates.Append(EncodeDate(2024, 2, 10));
  Dates.Append(EncodeDate(2024, 4, 5));
  
  // Sort chronologically
  Dates.Sort;
  
  // Get statistics
  Stats := Dates.Stats;
  try
    ShowMessage('Earliest: ' + DateToStr(Stats.Min));
    ShowMessage('Latest: ' + DateToStr(Stats.Max));
    ShowMessage('Median: ' + DateToStr(Stats.Median));
  finally
    Stats.Free;
  end;
end;

Working with Missing Values

var
  Values: TDoubleArray;
  Missing: TBooleanArray;
  Filtered: TDoubleArray;
  I: Integer;
begin
  // Create arrays
  Values.Resize(5);
  Missing.Resize(5);
  
  Values[0] := 10.0;
  Missing[0] := False;
  
  Values[1] := 0.0;
  Missing[1] := True;  // Missing
  
  Values[2] := 20.0;
  Missing[2] := False;
  
  Values[3] := 0.0;
  Missing[3] := True;  // Missing
  
  Values[4] := 30.0;
  Missing[4] := False;
  
  // Copy only non-missing values
  Filtered := Values.Copy(Missing);
  
  ShowMessage('Valid values: ' + IntToStr(Filtered.Count));
  // Shows: 3
  
  ShowMessage('Average: ' + FloatToStr(Filtered.Mean));
  // Shows: 20.0 (average of 10, 20, 30)
end;

Advanced: Custom Sort with Callback

type
  TPerson = record
    Name: String;
    Age: Integer;
  end;
  TPersonArray = array of TPerson;

var
  People: TPersonArray;
  Ages: TInt32Array;
  
procedure SwapPeople(const A, B: TInteger);
var
  Temp: TPerson;
begin
  Temp := People[A];
  People[A] := People[B];
  People[B] := Temp;
end;

begin
  // Create people array
  SetLength(People, 3);
  People[0].Name := 'Alice'; People[0].Age := 30;
  People[1].Name := 'Bob';   People[1].Age := 25;
  People[2].Name := 'Carol'; People[2].Age := 35;
  
  // Extract ages for sorting
  Ages.Resize(3);
  Ages[0] := People[0].Age;
  Ages[1] := People[1].Age;
  Ages[2] := People[2].Age;
  
  // Sort ages and swap people accordingly
  Ages.Sort(True, SwapPeople);
  
  // Now People array is sorted by age
  for var I := 0 to High(People) do
    ShowMessage(People[I].Name + ': ' + IntToStr(People[I].Age));
  // Shows: Bob: 25, Alice: 30, Carol: 35
end;

Performance Tips

Pre-allocate with Resize: Use Resize to allocate memory once rather than calling Append repeatedly for large datasets.
Binary Search: Always use SortedFind on sorted arrays instead of IndexOf for O(log n) instead of O(n) search time.
In-place Operations: Methods like Sort, Reverse, and Initialize work in-place without allocating new memory.
Copy Overhead: Copy creates a new array; avoid unnecessary copies for large datasets.

See Also

  • TDataItem - Uses these arrays for data storage
  • TDataKind - Determines which array type is used
  • TMissingData - Uses TBooleanArray for tracking missing values

Build docs developers (and LLMs) love