Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.03.2014, 22:08   #1
Карпотреских
 
Регистрация: 01.03.2014
Сообщений: 6
Сообщение Универсальная обработка динамических массивов разных записей

Здравствуйте!
Ситуация такова:
Есть несколько динамических массивов разных записей. С каждым массивом нужно выполнять похожие действия,
типа расширения на Х элементов, или удаления конкретного.
Проблема - массивов записей может быть очень много, поэтому
писать для каждого свою процедуру обработки неэффективно, ибо долго. Да и код становится до безобразия громоздкий. А нужно обрабатывать каждый массив. Возможно, какой-нибудь универсальной процедураой.
Вопрос - Существуют ли универсальные способы решения проблемы кроме следующих?

Способ 1) Тупо написать для каждого массива свою процедуру обработки.
Неэффективно, поэтому приемлемо только в крайнем случае.
Пример реализации первым способом:
Код:
type
X1=record //вот например первая структура
A,B,C,D,E:Integer;
end;

X2=record //вот вторая. Их может быть больше, но двух хватит для примера
A,B:boolean;
end;
//далее идут массивы, которые надо обрабатывать.
MX1=array of X1; 
MX2=array of X2;

implementation
//далее - процедуры обработки.
procedure DOIT_1(var X:MX1);
begin
  //увеличение размера массива первого типа
end;

procedure DOIT_2(var X:MX2);
begin
  //увеличение размера массива второго типа
end;
Способ 2) Можно использовать перегруженные функций, а значит фактически всёравно придётся писать много похожего кода (или, может, я неправильно пишу?), что не сильно отличается от первого варианта. К тому же, логика подсказывает, что перегруженные функции
работают чуть медленней, чем специальные. Поправьте, если неправ.
Пример реализации вторым способом:
Код:
type
X1=record //вот например первая структура
A,B,C,D,E:Integer;
end;

X2=record //вот вторая. Их может быть больше, но двух хватит для примера
A,B:boolean;
end;
//далее идут массивы, которые надо обрабатывать.
MX1=array of X1;
MX2=array of X2;

implementation
//далее - перегруженные процедуры обработки.
procedure DOIT_X(var X:MX1);overload;
begin
  //увеличение размера массива первого типа
end;

procedure DOIT_X(var X:MX2);overload;
begin
  //увеличение размера массива второго типа
end;
Способ 3) Можно использовать не записи, а обычные динамические массивы. Данный способ проблему решает и является наиболее приемлемым. Только вот в нём гораздо легче запутаться, да и попахивает изобретением велосипеда. В некоторых случаях может являться недостатком то, что на хранение всех данных выделяется одинаковое количество памяти, в данном случае четыре байта, ибо integer, что весьма избыточно например для boolean.
Пример реализации третьим способом:
Код:
Type
ZZ=array of integer; //это будет массив данных вместо записей типа X1, X2 и тд.
MZZ= array of ZZ; //затем мы говорим, что у нас будет много массивов разного размера

var
Mrec,Mdat:mzz; // объявляем переменные описанного типа, с ними мы и будем работать
//Mrec будет хранить информацию о типах данных, аналогично записям в первых двух способах
//Mdat будет хранить данные, структурированные согласно информации в Mrec.
implementation
//а вот и универсальная перегруженная процедура, задающая размеры любому массиву типа MZZ или типа ZZ 
procedure SET_ZZ(var X:MZZ;Y:integer); overload;
begin
setlength(X,Y); //расширяем массив объектов
end;

procedure SET_ZZ(var X:ZZ;Y:integer); overload;
begin
setlength(X,Y); //расширяем массив объектов
end;

//Сначала мы задаём структуру наших данных в Mrec.
Procedure SET_START_TYPES;
begin
//В идеале, структуру Mrec нужно формировать загружая из файла, но для примера сойдёт и формирование руками.
  SET_ZZ(Mrec,1);    //у нас всего один массив типов (то есть массив записей Х1=record и Х2=record), поэтому задаём размер 1
  SET_ZZ(Mrec[0],2); //у нас две записи в массиве, поэтому расширяем массив на два
  Mrec[0][0]:=5;//в первой записи у нас пять чисел (A,B,C,D,E:Integer);
  Mrec[0][1]:=2;//во второй записи у нас два числа
  //код, задающий размер структур
end;

Procedure SET_DATA;        //А вот пример работы с данными на основе типов, описанных в Mrec.
var LN1,LN2,i,j:integer; 
begin
//В идеале, структуру Mdat тоже нужно загружая из файла.
LN1:=1000;                //например, будем делать тысячу массивов структуры Х1
LN2:=Mrec[0][0];          //получаем количество элементов в Х1
SET_ZZ(MDat,LN1);         //расширяем массив массивов данных до тысячи
  for i := 0 to LN1-1 do
    begin
    SET_ZZ(Mdat[i],LN2); //каждый массиве расширяем массив данных согласно размеру Х1
    for j := 0 to LN2-1 do
      begin
      Mdat[i][j]:=random(222);//и заполняем случайными значениями
      end;
    end;
end;
Возможно, есть ещё?
Карпотреских вне форума Ответить с цитированием
Старый 01.03.2014, 22:22   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Исходя из представленных выше примеров могу посоветовать только два решения:

1) Матрица вариантов. Решает проблемы с разными типами. Обеспечивает универсальность кода для разных массивов. Однако далеко не всегда удобна в описании.

2) Создавать на каждый тип не массив а класс. Он будет работать со своим массивом. Если операции с массивом однотипны то можно наследовать их от базового класса

3)Работать не в массивами а с СУБД (например на основе XML). Создавать временные таблицы, куда будет помещаться разнотипная информация.

В твоем случае я бы наверное выбрал первый вариант, но оформил его в класс.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 01.03.2014, 22:27   #3
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Код:
type
  X1 = record
    A, B, C, D, E: Integer;
  end;

  X2 = record
    A, B: boolean;
  end;

  MX1 = array of X1;
  MX2 = array of X2;

var
  A: MX1;
  B: MX2;

procedure TForm1.FormCreate(Sender: TObject);
begin
  setlength(A, 10);
  setlength(B, 20);
end;
Это я к тому, для чего писать свои функции для расширения, если и так все работает.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )

Последний раз редактировалось BDA; 01.03.2014 в 22:29.
BDA вне форума Ответить с цитированием
Старый 01.03.2014, 22:39   #4
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
для чего писать свои функции для расширения, если и так все работает.
Так типы у массивов разные. Не хочет автор писать для каждого из них свой функционал.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 01.03.2014, 22:45   #5
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
Так типы у массивов разные. Не хочет автор писать для каждого из них свой функционал.
Ну да...
Смотря что за функционал. Если только расширение массива и удаление элементов, то не нужно писать по отдельному набору функций для каждого типа.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 01.03.2014, 22:54   #6
Карпотреских
 
Регистрация: 01.03.2014
Сообщений: 6
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
Это я к тому, для чего писать свои функции для расширения, если и так все работает.
Ты не понял, соль не в этом. Расширение - это всего лишь частный случай обработки, я привёл это в качестве примера. Кароче, нужно не только расширять. Ктамуже, расширять тоже нужно по-разному. Представь, что нужна и простая процедура расширения массива на +1, и процедура расширения на произвольное значение, и быстрые небезопасные, и медленные безопасные (с защитой от дурака). А теперь представь, что у нас не только расширение, но и перестановка разными вариантами, и удаление, и присвоение и чёрт знает что ещё. И самое главное, у нас могут быть тысячи типов массивов, которые нужно обрабатывать. перемножь эти три фактора, и ты получишь целую кучу однотипного быдлокода в виде специальных однотипных процедур, описанных мной в первых двух случаях. Соль в том, чтобы этого избежать, как в третьем примере.

Цитата:
Сообщение от Stilet Посмотреть сообщение
2) Создавать на каждый тип не массив а класс. Он будет работать со своим массивом. Если операции с массивом однотипны то можно наследовать их от базового класса
понял, попробую капнуть в этом направлении 8)
Цитата:
Сообщение от Stilet Посмотреть сообщение
1) Матрица вариантов. Решает проблемы с разными типами. Обеспечивает универсальность кода для разных массивов. Однако далеко не всегда удобна в описании.
а вот тут я ничего не понял оО Можно поконкретней?
Цитата:
Сообщение от Stilet Посмотреть сообщение
3)Работать не в массивами а с СУБД (например на основе XML). Создавать временные таблицы, куда будет помещаться разнотипная информация.
Не, этот вариант неприемлем, ибо скорость обработки данных очень важна. При таких условиях лишний раз ко всяким СУБД лучше не обращаться, и это даже без остальных ньюансов. Поэтому данные загружаются все сразу при старте приложения и также всей кучей сохраняются при завершении. Вобщем, хвала оперативе, и всё такое

Последний раз редактировалось Stilet; 01.03.2014 в 23:28.
Карпотреских вне форума Ответить с цитированием
Старый 01.03.2014, 23:35   #7
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
а вот тут я ничего не понял оО Можно поконкретней?
Ну поконкретнее могу только намекнуть на функцию VarArrayCreate()
Вот погули почитай про нее и функции иже с ними, и поймешь о чем я. Если от себя: Создать массив (матрицу) в котором будут элементы разных типов. Это сможет заменить тип записей, если в ячейки такого массива создавать другие массивы типа variant. Можно даже получить древесное (иерархическое) представление данных.
Цитата:
хвала оперативе
А я и не говорю о работе с ЖД. Многие СУБД умеют работать с временными таблицами, которые на диск не сбрасываются, так что скорости там вполне приемлемые.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 02.03.2014, 00:39   #8
Карпотреских
 
Регистрация: 01.03.2014
Сообщений: 6
По умолчанию

Цитата:
Ну поконкретнее могу только намекнуть на функцию VarArrayCreate()
Вот погули почитай про нее и функции иже с ними, и поймешь о чем я. Если от себя: Создать массив (матрицу) в котором будут элементы разных типов. Это сможет заменить тип записей, если в ячейки такого массива создавать другие массивы типа variant. Можно даже получить древесное (иерархическое) представление данных.
На первый взгляд выглядит приемлемо, буду копать.

Цитата:
А я и не говорю о работе с ЖД
даже если так, чтото это попахивает излишними высокоуровневыми наворотами, к которым у меня личная неприязнь :О особенно это касается VCL в серьёзных приложениях, вроде этого случая.
Карпотреских вне форума Ответить с цитированием
Старый 02.03.2014, 09:23   #9
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

Динамический массив Variant, чем не вариант?
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Старый 02.03.2014, 13:11   #10
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,882
По умолчанию

Можно предложить рассмотреть работу с Generic.Collections появившимися в Дельфи 2009 . Вводная
При этом, конечно, не лишним будет представление об ООП, и вообще опыт проектирования систем с высокоуровневой обработкой.
phomm вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Инициализация динамических массивов Алексей_2012 Общие вопросы Delphi 2 28.06.2013 16:48
Выполнить обработку массивов. предусмотреть описание массивов как динамических Vika_0_0 Паскаль, Turbo Pascal, PascalABC.NET 8 03.06.2012 10:12
Организация динамических массивов. MaSTeD C# (си шарп) 0 29.02.2012 10:18
обработка динамических массивов funky Помощь студентам 0 11.05.2009 17:53