Дмитрий Рябов дата публикации 21-10-2003 13:29 Реализация ассоциативных массивов в Delphi
На практике часто возникает потребность сохранять и обрабатывать данные
в массивах, осуществляя доступ к элементам не по индексу, а по ключу. Для
этого используются ассоциативные массивы, которые есть, например, во многих
скриптовых языках. В Delphi на уровне языка такая структура отсутствует.
В качестве замены часто используются контейнерные классы TStringList,
TParams и т.п., но они весьма неудобны в использовании и недостаточно
функциональны. К тому же появляется необходимость заботиться об уничтожении
экземпляра класса, что зачастую порождает лишние try..finally..end.
Предлагаю вашему вниманию реализацию ассоциативных массивов, построенную на
использовании интерфейсов, которая избавлена от недостатков стандартных
контейнеров. Из её преимуществ можно отметить: удобное использование, неплохую
производительность, отсутствие небходимости принудительного уничтожения,
нескольно представлений одного массива, использование ключей разных типов,
наличие функций итератора, удобное использование многомерных массивов.
Далее привожу пример использования массивов:
program Example;
uses
Arrays;
procedure Main;
var
I: IIntArray;
S: IStrArray;
V: IVarArray;
M: IMltArray;
begin
I := CreateArray;
I['a'] := 5;
I['b'] := 1;
I['c'] := 4;
I['d'] := 2;
I['e'] := 3;
WriteLn('Original array');
I.First;
while not I.Eof do
begin
WriteLn('[', I.CurrentKey, '] = ', I.CurrentValue);
I.Next;
end;
I.Sort;
WriteLn('Sorted array');
I.First;
while not I.Eof do
begin
WriteLn('[', I.CurrentKey, '] = ', I.CurrentValue);
I.Next;
end;
S := I.Instance;
WriteLn('Two views of one array');
S.First;
while not S.Eof do
begin
WriteLn('[', S.CurrentKey, '] + ''10'' = ', S.CurrentValue + '10');
WriteLn('[', I.CurrentKey, '] + 10 = ', I.CurrentValue + 10);
S.Next;
end;
V := S.Instance;
V.Clear;
V['integer'] := 10;
V['string'] := '10';
WriteLn('Variant type conversion');
V.First;
while not V.Eof do
begin
WriteLn('[', V.CurrentKey, '] + 10 = ', V.CurrentValue + 10);
WriteLn('[', V.CurrentKey, '] + ''10'' = ', V.CurrentValue + '10');
V.Next;
end;
S.Clear;
S[False] := 'boolean';
S[0] := 'integer';
S[0.0] := 'float';
S['0'] := 'string';
WriteLn('Variant type keys ;)');
S.First;
while not S.Eof do
begin
WriteLn('[', S.CurrentKey, '] = ', S.CurrentValue);
S.Next;
end;
M := V.Instance;
M.Clear;
M['A']['a'].AsInteger := 1;
M['A']['b'].AsInteger := 2;
M['A']['c'].AsInteger := 3;
M['B']['a'].AsInteger := 4;
M['B']['b'].AsInteger := 5;
M['B']['c'].AsInteger := 6;
M['C']['a'].AsInteger := 7;
M['C']['b'].AsInteger := 8;
M['C']['c'].AsInteger := 9;
WriteLn('Multidimensional array');
M.First;
while not M.Eof do
begin
M.CurrentValue.First;
while not M.CurrentValue.Eof do
begin
WriteLn('[', M.CurrentKey, ',', M.CurrentValue.CurrentKey, '] = ',
M.CurrentValue.CurrentValue.AsInteger);
M.CurrentValue.Next;
end;
M.Next;
end;
WriteLn('Arrays is free');
end;
var
L: Integer;
begin
L := AllocMemSize;
Main;
WriteLn('Memory leak: ', AllocMemSize - L, ' bytes');
ReadLn;
end.
| |
К материалу прилагаются файлы:
[Массивы]
Обсуждение материала [ 07-05-2014 13:18 ] 29 сообщений |