Welcome to
aleprojects.com

Associative array. TAleArray and TAleValue Delphi classes.

Associative array is a data structure containing pairs of unique keys and associated data. This Delphi implementation of associative array allows to use integer and string keys. It is possible to extend basic class in order to use keys of other types. Keys are stored in red-black tree for faster access to array elements. Values of array elements can be TObject's descendants. The value can be also of TAleArray type - this is way how nested arrays are implemented.

TAleArray class encapsulates properties and methods for inserting, deleting, sorting elements and iterating over array. TAleValue class can keep single values of type: Boolean, LongInt, Int64, Double, Currency, TDateTime, PWideChar. Array elements of TAleValue type can be compared and sorted.

Download

Example

var A:TAleArray;
    V:TAleValue;

begin
//create array
A := TAleArray.Create;

//create first element with 'Key_0' key and integer value
V := TAleValue.Create;
V.IntegerValue := 100;
A['Key_0'] := V;

//create second element with integer key 1 and text value
V := TAleValue.Create;
V.TextValue := AleWSNew(PWideChar(WideString('Some text')));
A.ByIntKey[1] := V;

//create third element with 'Key_1' key and text value
V := TAleValue.Create;
V.TextValue := AleWSNew(PWideChar(A['Key_0'].AsText + ' ' + A.ByIntKey[1].AsText));
A['Key_1'] := V;

//remove second element
A.ByIntKey[1] := nil;
...
A.Free;
end;

Comments

Element with text key is accessed as A['Key_0'], but element with integer key is accessed as A.ByIntKey[1]. TAleValue class has the property ByTextKey[Index:WideString]:TAleValue and it is defined as default. Function AleWSNew - internal string format for TextValue property of TAleValue class must match the WideString format - four bytes before first character are string length multiplied by SizeOf(WideChar) = 2 and #0 in the end of string.

Usage

All operations on associative array are performed by methods and properties of TAleArray class. It is necessary to define variable of type TAleArray.

var A, A1: TAleArray;
    N: LongInt;
...
A := TAleArray.Create;
A1 := TAleArray.Create;
A['Item_0'] := A1;
N := A.Count;
...

Adding and accessing elements

Elements of an associative array are accessed by properties ItemByTextKey[const Key:WideString]:TObject and ItemByIntKey[Key:LongInt]:TObject. Properties return nil if no element exists with the a specified key. On assigning value to properties the following actions take place: if there is no element with a specified key, it will be created; if an element exists, then a new value will be set; if the property is set to nil, then the element with specified key will be removed. String keys are case independent.

Method Add adds new element with integer key set to maximal existing integer key +1.

procedure TAleArray.Add(NewValue:TAleValue);

Element in nested array also can be accessed by a single call to property ItemByTextKey.

var A,V: TAleValue;
    i: LongInt;
...
A := TAleValue.CreateArray;
V := TAleValue.Create;
V.IntegerValue := 525;

A['Level0;Level1;Level2'] := V;
...
i := A['Level0;Level1;Level2'].IntegerValue;
// or
i := TAleValue(TAleArray(TAleArray(A['Level0'])['Level1'])['Level2']).IntegerValue;

On assigning V to A['Level0;Level1;Level2'] all elements with nested arrays will be created automatically if necessary. Property IndexSeparator of type WideChar defines character which separates keys. This works only with the string keys.

Property Count returns number of elements in associative array.

Iteration over array

Method GetNext iterates over associative array. The array elements are arranged in the order they were added to the array. Method GetNext is defined as

function TAleArray.GetNext(var O:TObject; var lpKey:Pointer; var KeyType:Longint):Boolean;

parameter O contains value of next element of the array,
parameter lpKey is a pointer to key value of the element (it can point to PWideChar string or to LongInt value),
parameter KeyType indicates type of the key (0 - integer key (constant aa_intkey), 1 - string key (constant aa_textkey) for correct type casting of the lpKey^ value.

Method returns false when it reaches to the end of the array. Setting parameter O to nil starts iteration from the beginning of the array.

var V: TObject;
    A: TAleArray;
    wS: WideString;
    lpKey: Pointer;
    i:LongInt;
...	

//print the content of array to Memo1
V := nil;
While A.GetNext(V, lpKey, i) do
 begin
   if i = aa_intkey then wS := IntToStr(Integer(lpKey^)) else wS := WideString(PWideChar(lpKey));
   wS := '[' + wS + '] => ';
   if V is TAleValue then wS := wS + V.AsText else wS := wS + 'Some object';
   Memo1.Lines.Append(wS);
 end;

Sorting

Method Sort of TAleArray class sorts an array.

procedure TAleArray.Sort(dwParam:Longint=0);

Highest bit of the dwParam is reserved and defines sort order (0 - ascending, 1 - descending). Parameter dwParam is passed to virtual method ArrayCompareElements which compares array elements. Method can be overridden in descendant classes.

Sorting violates the order of the array elements. Before the sorting the elements are in the order they were added to array. Adding elements or setting new values generally violates sort order.

After sorting in ascending order the groups of sorted elements will be placed in the following order of types: first elements of type TAleValue and other elements next. Elements of type TAleValue are sorted in order: Booleans, Numerics, Dates/Times, Strings. And vice versa in the descending order. In order to change the sequence of types, or to compare the TObjects or TAleArrays, method ArrayCompareElements should be overridden.

sorted by ascending order array

[false, false, true, 0, 0.1, 2, 10, 1.344E+23, 03-mar-1999, 09-aug-2010, 'AAA', 'aaa', 'dd', 'zz',TObject2, TObject1]

Method Sort is based on QuickSort algorithm. Method requires additional memory for sorting operation in size of N*SizeOf(Pointer) bytes because class TAleAssociativeArray uses doubly-linked, bidirectional list to keep order of array elements, not an index.

var A:TAleArray;
...
//ascending
A.Sort; 
//descending
A.Sort($80000000); 
...

Working with keys

Method Keys returns all keys of associative array.

function TAleArray.Keys(bOrdered:Boolean=true):TAleAssociativeArray;

The elements of the returned array have integer keys in range 0..N-1. Where N is a number of elements in the original array. If the parameter bOrdered is true, the returned array will be sort by ascending order.

Emptying and destroying array, links to elements

Method Clear removes all elements from associative array. Method Free is called for each removed element. After emptying or destroying of an array all links to its elements or data of elements become illegal.