Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> TObjectList и работа с ним 
:(
    Опции темы
1122
  Дата 25.5.2010, 16:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 109
Регистрация: 24.10.2007

Репутация: нет
Всего: нет



Создаю объект TobjectList. Заполняю. Далее нужно оставить половину элементов от того, что есть. Перегоняю эту половину во временный ObjectList и хочу очистить исходный, чтобы затем вернуть туда эти элементы из временного. Но сыпятся ошибки после того, как я пытаюсь вызвать clear или delete по элементно.
Как правильно очищать такие массивы?

Выдержки из кода:
Код

 procedure TForm1.FormCreate(Sender: TObject);
begin
Population:=TobjectList.Create;
TempPopulation:=TobjectList.Create;
end;


Таким способом первоначально формирую массив:
Код

for i:=0 to N-1 do
begin
    Osob:=TOsob.Create;
    Osob.fenotip:=-3 + i*0.12;
    Osob.P:= 0.2*osob.fenotip+osob.fenotip*sin(8.9*osob.fenotip)+0.9*cos(1.5*osob.fenotip-2);
    Osob.genotip:=inttobin(i,col);
    Population.add(osob);
end;


Далее массив дозаполняется элементами:

Код

for i:=0 to count-1 do
begin
Osob2:=Tosob.create;
Osob2.genotip:=agen1[i];
Population.Add(Osob2);
end;

for i:=0 to count-1 do
begin
Osob2:=Tosob.create;
Osob2.genotip:=agen2[i];
Population.Add(Osob2);
end;


for i:=0 to Population.Count-1 do
begin
(Population.Items[i] as Tosob).fenotip:= -3 + i*r;
x:= -3 + i*r;
(Population.Items[i] as Tosob).P:=  0.2*x+x*sin(8.9*x)+0.9*cos(1.5*x-2);
end;


И вот дальше нужно оставить в Population только N значений. Как это сделать?
Спасибо.




PM MAIL   Вверх
Dom
Дата 25.5.2010, 17:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 121
Регистрация: 7.8.2005

Репутация: 1
Всего: 4



Если все равно какие элементы удалять, то можно например так

Код

for i := Population.Count - 1 downto N do
  Population.Delete(i);

PM MAIL   Вверх
1122
Дата 25.5.2010, 17:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 109
Регистрация: 24.10.2007

Репутация: нет
Всего: нет



Вбил ваш код. Ошибка. Аксесс виалэйшен.
PM MAIL   Вверх
1122
Дата 25.5.2010, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 109
Регистрация: 24.10.2007

Репутация: нет
Всего: нет



Странные дела.

Если написать такой код:
Код

for i := 50 to population.count do
Population.Delete(i);

и этот самый каунт будет равен 92, то на 71 итерации, когда будет удаляться 71 элемент произойдет ошибка.Т.к. удаляя на первой итерации 50-тый элемент каунт уменьшается на один и т.д. Когда дойдем до 71 итерации и нужно будет удалить 71й элемент, то его уже не будет.
Что можно сделать?

Это сообщение отредактировал(а) 1122 - 25.5.2010, 18:05
PM MAIL   Вверх
kami
Дата 25.5.2010, 19:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Цитата(1122 @  25.5.2010,  18:03 Найти цитируемый пост)
Странные дела.

Ничего странного. Пойдем по порядку.

Цитата(1122 @  25.5.2010,  16:47 Найти цитируемый пост)
нужно оставить половину элементов от того, что есть. Перегоняю эту половину во временный ObjectList и хочу очистить исходный, чтобы затем вернуть туда эти элементы из временного. 

По умолчанию ObjectList является владельцем элементов, которые он содержит. Это значит, что при удалении объекта из него, или при очищении списка этот объект УНИЧТОЖАЕТСЯ. Если нужно, чтобы этого не происходило, то конструктор вызывать нужно так:
Код

Population:=TobjectList.Create(False);

Но нужно четко осознавать, что в этом случае об освобождении объектов, добавленных в список, нужно позаботиться самому, иначе пойдут утечки.
При Вашем способе (загнать половину во временный список, очистить исходный, перенести обратно) получается следующая последовательность:
1. В исходном списке содержатся ссылки на объекты.
2. Часть этих ссылок мы копируем во временный список.
3. Очищаем исходный список. При этом, т.к. список был создан с конструктором по-умолчанию, он является владельцем добавленных в него объектов. При очищении он высвобождает все содержащиеся в нем объекты, ссылки на них становятся не-валидными.
4. Копируем ссылки на (уже уничтоженные) объекты в исходный список. Но толку от них уже нет...

Цитата(1122 @  25.5.2010,  16:47 Найти цитируемый пост)
И вот дальше нужно оставить в Population только N значений. Как это сделать?

Код, предложенный Dom правильный. Вы не обратили внимание на то, что используется цикл на уменьшение for ...downto, а не for...to.
В случае использования этого кода настоятельно рекомендуется оставить ObjectList владельцем объектов.

Добавлено @ 19:20
Цитата(kami @  25.5.2010,  19:15 Найти цитируемый пост)
используется цикл на уменьшение for ...downto

В дополнение: так как индексация элементов в списке начинается с нуля, прошу обратить внимание на
Цитата(Dom @  25.5.2010,  17:09 Найти цитируемый пост)
for i := Population.Count - 1 downto N do



Это сообщение отредактировал(а) kami - 25.5.2010, 19:21
PM MAIL WWW   Вверх
underchronos
Дата 25.5.2010, 20:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 25.7.2008

Репутация: нет
Всего: нет



kami
А не проще тогда в этом цикле воспользоваться функцией Extract?

Код

for i := Population.Count - 1 downto N do
  TempPopulation.Add(Population.Extract(i));


Разве для этого метода будет важно с каким флагов Create? Он удалит ссылку из своего списка и вернет ее, не удалив сам объект.



Это сообщение отредактировал(а) underchronos - 25.5.2010, 20:49
PM MAIL   Вверх
kami
Дата 25.5.2010, 21:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Цитата(underchronos @  25.5.2010,  20:49 Найти цитируемый пост)
А не проще тогда в этом цикле воспользоваться функцией Extract?

"Из любого безвыходного положения есть по меньшей мере два выхода" (с) не помню чье.
Возможно, Вам проще сделать так.
Но мне было бы лень заводить второй список, тратить время процессора на его создание/заполнение/копирование_в_исходный/уничтожение, когда можно просто воспользоваться кодом Dom, зная при этом что OwnObjects=True.
Всё зависит от задачи...

Upd: в Вашем случае при перегоне из временного в основной также нужно будет пользоваться Extract, в противном случае - опять контроль OwnObjects временного списка...

Это сообщение отредактировал(а) kami - 25.5.2010, 21:32
PM MAIL WWW   Вверх
underchronos
Дата 25.5.2010, 21:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 25.7.2008

Репутация: нет
Всего: нет



Цитата(kami @  25.5.2010,  21:27 Найти цитируемый пост)
"Из любого безвыходного положения есть по меньшей мере два выхода" (с) не помню чье.

Надо запомнить!  smile 


Цитата(kami @  25.5.2010,  21:27 Найти цитируемый пост)
Всё зависит от задачи...

Да я, честно признаться, задачу не понимаю.  smile  Я понял из слов создателя топика -- нужно перегнать часть исходного списка в другой. А потом вернуть его по необходимости если что...  Или он хочет просто очистить половину исходного списка. 

Это сообщение отредактировал(а) underchronos - 25.5.2010, 21:33
PM MAIL   Вверх
kami
Дата 25.5.2010, 21:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

Репутация: 23
Всего: 72



Цитата(underchronos @  25.5.2010,  21:33 Найти цитируемый пост)
Я понял из слов создателя топика -- нужно перегнать часть исходного списка в другой. 

Вообще-то исходная проблема звучала как
Цитата(1122 @  25.5.2010,  16:47 Найти цитируемый пост)
И вот дальше нужно оставить в Population только N значений. Как это сделать?

И решение было дано в первом же ответе smile

Кстати, чем-то этот код напоминает пример игры на Паскале из учебников - "Цивилизация" (не путать со стратегией). Там по определенным условиям в "соседних" клетках "рождались" новые элементы, старели (просто от этапа к этапу), умирали от перенаселенности (когда в 3 или 4 соседних клетках тоже были элементы) и т.п...
PM MAIL WWW   Вверх
bems
Дата 26.5.2010, 00:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 31
Всего: 88



kami, это жизнь а не цивилизация


--------------------
Обижено школьников: 8
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0779 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.