Форум: "Начинающим";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];
ВнизСортировака с помощью TObjectList Найти похожие ветки
← →
Константин (2010-03-05 11:12) [0]Скажите пожалуйста возможно ли отсортировать TObjectList, используя метод объекта в роли TListSortCompare. Это нужно для того, чтобы отсортировать индексированные объекты, то есть фактически отсортировать индексы объектов, хранящиеся в TObjectList, а сами объекты оставить нетронутыми в хранилище, являющимся свойством класса, метод которого и хочу использовать для сортировки. В этом методе будут доступны объекты хранилища через их индексы.
← →
Ega23 © (2010-03-05 11:16) [1]э-э-э-э... У него же есть стандартный механизм?
← →
Константин (2010-03-05 11:40) [2]
> У него же есть стандартный механизм?
я его и использую
Есть хранилище объектов, которое не надо сортировать:
TStoredObjects
Есть индексы, индексирующие объекты в TStoredObjects
TStoredObjectIndexes = class (TObjectList)
end;
Есть класс оперирующий данными
TMainClass = class
SO: TStoredObjects;
SOI: TStoredObjectIndexes
procedure Proc1;
function SortByIndexes(SOI1, SOI2: Integer): Integer;
end;
Есть два метода TMainClass
procedure Proc1;
begin
SOI.Clear;
for i := 0 to SO.Count - 1 do
SOI.Add(TObject(i));
SOI.Sort(@self.SortByIndexes);
end;
function SortByIndexes(SOI1, SOI2: Integer): Integer
begin
Result := IfThen(SO[SOI1].Value < SO[SOI2].Value, -1, 1);
end;
Это приблизительно. Но это не работает. Можно было TStoredObjects унаследовать от TObjectList, но эти объекты надо оставлять в своём порядке жестко.
← →
Ega23 © (2010-03-05 11:42) [3]Храни сортированый список индексов.
← →
Константин (2010-03-05 11:50) [4]
> Храни сортированый список индексов.
не понял. TMainClass должен определять, по каким правилам как бы сортировать TStoredObjects. Соответсвенно с помощью TStoredObjectIndexes он будет обращаться к TStoredObjects как ему надо.
← →
Игорь Шевченко © (2010-03-05 11:54) [5]
> TStoredObjectIndexes = class (TObjectList)
> end;
а какие в нем объекты ?
← →
Константин (2010-03-05 11:56) [6]
> а какие в нем объекты ?
приводимые Integer
← →
Константин (2010-03-05 11:57) [7]может я что то недоделал, пишет на Sort(@имя метода ) Variable required
← →
Игорь Шевченко © (2010-03-05 11:59) [8]TListSortCompare - это не метод
← →
Константин (2010-03-05 12:04) [9]
> TListSortCompare - это не метод
ну да, в этом то и вопрос, как сделать. Если я выношу SortByIndexes как правильнго, в функцию, то я же не вижу тогда TMainClass.SO данных. Может можно как то вернуть каким то методом TMainClass объект TListSortCompare ,который будет иметь доступ к полям TMainClass ?
← →
Игорь Шевченко © (2010-03-05 12:10) [10]
> в этом то и вопрос, как сделать
приведением типа
← →
Константин (2010-03-05 12:12) [11]Как вариант вижу создать не просто набор индексов, а набор объектов-индексов, хранящих непосредственно индекс и ссылку на индексируемый объект,тогада в TListSortCompare будет доступ для сравнения, но не хочется как то всё инкапсулировать получше.
← →
Константин (2010-03-05 12:14) [12]
> приведением типа
оО точно, сейчас попробую
← →
Константин (2010-03-05 12:16) [13]
> приведением типа
а как это написать. Пробую такSOI.Sort(TListSortCompare(@self.SortByIndexes));
← →
Константин (2010-03-05 12:25) [14]
SOI.Sort(@(TListSortCompare(self.SortByIndexes)))
и так не пашет. Не подскажите как это сделать?
← →
Игорь Шевченко © (2010-03-05 12:28) [15]
> а как это написать
Хранить во втором списке не индексы, а сами объекты. И не TObjectList, а TList
← →
Константин (2010-03-05 12:39) [16]
> И не TObjectList, а TList
а почему не TObjectList, какие то проблемы могут возникнуть?
← →
Игорь Шевченко © (2010-03-05 12:43) [17]
> а почему не TObjectList
Если один объект в двух списках и каждый список будет удалять объекты, в нем содержащиеся, то объект будет удален дважды и это будет проблемой.
← →
MBo © (2010-03-05 13:23) [18]1. прототип
type TListSortCompare = function (Item1, Item2: Pointer): Integer;
функции сравнения неплохо бы ему соответствовать.
Послабление в проверке типов позволяет объявлять аргументы Integer, но это ни к чему.
2. В функцию сравнения передаются указатели, т.е. для TObjectList - сами объекты
3. Результат функции - не только -1 и +1, при равенстве ключей функция должна возвращать 0, иначе рано или поздно наступишь на грабли.
← →
Константин (2010-03-05 13:24) [19]а TObjectList.Create(False) же вроде не сделает таких проблем?
и всё равно SortByIndexes придётся выносить из класс как я понял да?
← →
Игорь Шевченко © (2010-03-05 13:30) [20]
> а TObjectList.Create(False) же вроде не сделает таких проблем?
не сделает
← →
Константин (2010-03-05 13:39) [21]
> не сделает
а если я сделаю список объектов в TObjectList, такихTIndex = class
public
Index: Integer;
StoreObjectLink: TStoredObject
constructor Creater(PIndex: Integer; PStoreObj: TStoredObject);
begin
Index := PIndex;
StoreObjectLink := PStoreObj;
end;
end
и проинициализирую индексыbegin
SOI.Clear;
for i := 0 to SO.Count - 1 do
SOI.Add(TIndex.Create(i, SO[i]));
?
так а SortByIndexes я никак не смогу сделать методом класса, да?
← →
Константин (2010-03-05 13:41) [22]
> не сделает
а, не сделает в смысле будет как TList ? )))
← →
MBo © (2010-03-05 13:48) [23]>SortByIndexes я никак не смогу сделать методом класса, да?
Штатную функцию сравнения - нельзя, но можно ввести свой метод сортировки.
← →
Константин (2010-03-05 13:50) [24]блин, так можно сделать просто два TObjectList один хранит объекты как бы, а другой как бы только ссылки на них, без всяких индексов, ну и второй не может удалять объекты. Правильно?
Чё-то я вообще запутался. Просто у меня есть структуры данных, каждая из которых должна указывать на исходные объекты. При пересортировке объектов, надо синхронизировать ссылки на них в структурах данных. Хочется как то обойти этот гемор, тут надо что то типа наблюдателя.
← →
Константин (2010-03-05 13:51) [25]
> но можно ввести свой метод сортировки.
что значит ввести? Переписать вызов у TList ?
← →
MBo © (2010-03-05 14:11) [26]>Просто у меня есть структуры данных, каждая из которых должна указывать на исходные объекты
TObjectList и хранит ссылки на объекты (адреса, указатели)
при сортировке тела объектов остаются на месте, а меняются меcтами только указатели в списке.
Пример
список:
Петя 3-й переулок Навуходоносора 7
Вася ул. м. Бертольда Шварца 5
сортируем по номеру дома
Вася ул. м. Бертольда Шварца 5
Петя 3-й переулок Навуходоносора 7
Вася и Петя никуда не переехали, изменился лишь список.
Или почему-то понадобились указатели на указатели?
← →
Константин (2010-03-05 14:22) [27]
> Или почему-то понадобились указатели на указатели?
допустим есть 3 классаъ
TFirst = class
StoredObjectIndex1: Integer;
StoredObjectIndex2: Integer;
StoredObjectIndex3: Integer;
end;
TSecond = class
StoredObjectIndex1: Integer;
StoredObjectIndex2: Integer;
TAnyClass = class
First: TFirst;
Second: TSecond;
Все поля Integer указывают на индекс в SO. Если я его (SO) отсортирую, то эти все поля будут указывать, не на те объекты. Поэтому надо синхронизировать. Или праильнее хранить не индексы а ссылки?
← →
Константин (2010-03-05 14:56) [28]это я типа ламер?
Надо хранить в TFirst ссылки на объекты да? а управление их памятью оставит на SO и сортировать его как угодно.
← →
Константин (2010-03-05 15:14) [29]если это действительно так, то как тогда организовывать ссылки без приведения типов в таких случаях
TClass1 = class
Object2: TObject; //требуется класс TClass2 но он объявляется позже
end;
TClass2 = class
Objtct1: TClass1;
end;
Первое что приходит в голову так это в TClass2 сделать
proprety Object2: TClass2 read Get write Put;
и в методах доступа приводить тип, но так опять же не получиться по вышесказанной причине.
Что делать тогда?
← →
Константин (2010-03-05 15:31) [30]Уважаемые мастера, вразумите меня пожалуйста
← →
Игорь Шевченко © (2010-03-05 16:01) [31]Я не могу понять а) в чем задача ? б) в чем проблема ?
Только не надо про классы и ObjectListы - это уже конкретная реализация, лучше про задачу с начала
← →
Константин (2010-03-05 16:06) [32]Проблема в моем понимании реализации алгоримтов в Daphi оперируя разнообразными струкурами и типами данных. Вот один из примеров рельной проблемы:
> TClass1 = class
> Object2: TObject; //требуется класс TClass2 но он объявляется
> позже
> end;
> TClass2 = class
> Objtct1: TClass1;
> end;
Как её обычно решают. Это выглядит как циклическая ссылка. Но я же могу сделать чтобы она таковой не была!!?
← →
Игорь Шевченко © (2010-03-05 16:10) [33]
> Как её обычно решают
type
TClass2 = class;
TClass1 = class
Class2: TClass2;
end;
TClass2 = class
Class1: TClass1;
end;
так решают
← →
Константин (2010-03-05 16:16) [34]
> так решают
спасибо.
И еще, если я добавляю уже созданный объект в TObjtctList то копируется ссылка правильно? Два объекта не создаются. При какой-то сложной реализации каких-то алгоритмов, допустим, создаются объекты в хранилище, в моем случае список TObjectList. А операции с их данным проводятся лишь с помощью указателей на них, а не индексацией в TObjectList. Это правильный подход?
← →
Игорь Шевченко © (2010-03-05 16:43) [35]
> И еще, если я добавляю уже созданный объект в TObjtctList
> то копируется ссылка правильно? Два объекта не создаются.
> При какой-то сложной реализации каких-то алгоритмов, допустим,
> создаются объекты в хранилище, в моем случае список TObjectList.
> А операции с их данным проводятся лишь с помощью указателей
> на них, а не индексацией в TObjectList. Это правильный подход?
>
Извини, не понимаю. TObjectList всегда хранит только указатели на объекты (как и его предок, TList), поэтому как в этом свете понимать твою фразу - я не знаю.
← →
Константин (2010-03-05 19:21) [36]да я запутанно объясняю. В любом случае спасибо за помощь!
← →
Юрий Зотов © (2010-03-05 21:49) [37]Так я ничего и не понял...
← →
Константин (2010-03-06 17:08) [38]
> Так я ничего и не понял...
чтобы иметь доступ к каким-то коллекциям объектов, я использовал индесы объектов в коллекции, т.е порядковый номер объекта. Это позволяло не заботиться о ссылках на объекты как указателях, это были просто переменные целого типа (конечно глупый аргумент) Но появлялось очень много гемороя, когда нужно было что то пербрать или отсортировать. Надо было сортировать индексы досупа, а не объекты. Я знал, что это бред, потому что, напрмер на PHP, я пишу явно не так.
Вот я наконец понял, что оперировать как раньше не надо, это не удобно и неправильно. Надо просто эффетивно работать с указателсями и всё.
← →
Константин (2010-03-11 12:09) [39]Кому интересно можно TListSortCompare вписать как подпроцедуру метода, тогда она будет как бы инкапсулирована в классе.
← →
Демо © (2010-03-11 12:30) [40]
> Юрий Зотов © (05.03.10 21:49) [37]
> Так я ничего и не понял...
Действительно, автор так и не сформулировал, что же ему нужно.
> Константин (11.03.10 12:09) [39]
> Кому интересно можно TListSortCompare вписать как подпроцедуру
> метода, тогда она будет как бы инкапсулирована в классе.
>
Да уж...
Страницы: 1 2 вся ветка
Форум: "Начинающим";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];
Память: 0.54 MB
Время: 0.055 c