Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   Flex (http://www.flasher.ru/forum/forumdisplay.php?f=84)
-   -   Работа с коллекциями (http://www.flasher.ru/forum/showthread.php?t=167642)

zorexundra 12.09.2011 11:41

Работа с коллекциями
 
Здравствуйте!
Помогите решить задачу.
Есть множество объектов типа ArrayCollection, со своей структурой.
Для ускорения работы с данными, я хочу структуировать представление ArrayCollection в соответствии со своими задачами.
Для этого я формирую списки индексов элементов ArrayCollection с помощью метода getItemIndex().
Но вот незадача: после сортировки ArrayCollection элементы меняют свой индекс.
Подскажите, как можно проиндексировать объект ArrayCollection, чтобы потом по индексу элемента можно было обратиться к последнему, не взирая на операции вставки, сортировки, удаления.

GBee 12.09.2011 12:54

Ох вы написали. Может параллельно набивать/удалять эти элементы в хеш-таблицу?

zorexundra 12.09.2011 13:07

Цитата:

Сообщение от GBee (Сообщение 1030619)
Ох вы написали. Может параллельно набивать/удалять эти элементы в хеш-таблицу?

Думаю такой вариант вполне рабочий. Но это приведёт к дублированию данных и увеличению потребляемой приложением памяти. Также придётся придумать алгоритм синхронизирующий два источника данных. Перефразируя фразу "Шурик, Вы комсомолец? Это же не наш метод!" из известного кинофильма:
- GBee, Вы Flash-разработчик? Это же не наш метод! :)

GBee 12.09.2011 13:19

Почему, просто будет две ссылки на один и тот же объект. Синхронизация - работы на 10 минут. Я за быстродействие :о)

Добавлено через 2 минуты
У себя постоянно использую массив+таблица. Массив для массовых операций, таблица - быстро вытащить нужный элемент.

zorexundra 12.09.2011 13:46

GBee, поправьте меня, если я ошибаюсь:
Код AS3:

var testArCol:ArrayCollection = new ArrayCollection(new Array(2,1,8,5));
var elementTestArCol:Object = testArCol.getItemAt(0);
trace(elementTestArCol); // 2
testArCol.removeItemAt(0);
trace(testArCol.getItemAt(0)); // 1
trace(elementTestArCol); // 2

Тобишь, метод getItemAt() вернул нам объект, а не ссылку на него.
Возможно я чего-то недопонимаю в механизме присвоения ссылок в AS.

GBee 12.09.2011 14:06

Цитата:

В ActionScript 3.0 все аргументы передаются ссылками, поскольку все значения хранятся как объекты. Однако объекты, принадлежащие примитивным типам данных, к которым относятся Boolean, Number, int, uint, и String, имеют специальные операторы, которые позволяют воспроизвести поведение объектов при передаче аргументов значениями.
Отсюда

zorexundra 12.09.2011 14:36

Код AS3:

function passByRef(objParam:Object):void { 
var testAr:Array = new Array(objParam.x, objParam.y);
objParam.x++;
objParam.y++;       
trace(objParam.x, objParam.y);                               
trace(testAr[0], testAr[1]);
}
var objVar:Object = {x:10, y:15};
trace(objVar.x, objVar.y); // 10 15
passByRef(objVar); // 11 16 10 15
trace(objVar.x, objVar.y); // 11 16

GBee, каким образом я должен на основании заданной коллекции создать коллекцию, "удобоваримую" для меня, не копируя значения исходных данных?
...Хм. Разобрался -
Код AS3:

var testAr:Array = new Array(objParam);

Всё-таки хочется работать с исходным объектом ArrayCollection не прибегая к методам перебора.
Есть такая возможность в Flex-framework?

GBee 12.09.2011 14:57

Цитата:

Всё-таки хочется работать с исходным объектом ArrayCollection не прибегая к методам перебора.
Есть такая возможность в Flex-framework?
Нихт понимайтен :о)) Перефразируйте, пожалуйста. А что вам нужно в итоге? Не в вашем виденьи, а по ТЗ/таску? Может вы зря мучаетесь.

zorexundra 12.09.2011 15:22

Есть множество ArrayCollection соответствующих таблицам серверной БД.
Всё это множество нужно систематизировать на стороне клиента и свести в один ArrayCollection.
В этом конечном ArrayCollection должны быть значения идентифицирующие исходные итемы множества ArrayCollection (теперь я так понимаю ссылки на эти итемы), по которым можно быстро обратиться к исходным данным.
Механизм наподобие реляционных БД: есть идентификатор поля, по нему получаем доступ к строке таблицы. Или механизм хеш-таблицы.
Цель - ускорить работу с данными учитывая переменные условия.

Кажется, Вы помогли мне в формировании понимания путей реализации:
необходимо создать коллекцию ссылок на исходные элементы.
Но остаётся иллюзия, что можно как-то пометить элементы исходных коллекций, чтобы потом обратиться к ним по этим меткам. Такой путь более приятен для моих стереотипов.

saprahan 12.09.2011 15:32

Цитата:

Сообщение от zorexundra (Сообщение 1030646)
Но остаётся иллюзия, что можно как-то пометить элементы исходных коллекций, чтобы потом обратиться к ним по этим меткам. Такой путь более приятен для моих стереотипов.

Это не иллюзия. На практике такой кейс и вправду встречается. Рекомендую при инициализации коллекции заводить также мапу: ключ->айтем. Можно, например, экстендить ArrayCollection, добавить параметр itemsMap, и в конструкторе ArrayCollection'a (а также, возможно в оверрайде метода refresh) прописать инициализацию мапы из сорса. Назвать MappedArrayCollection.

Dimitry_II 12.09.2011 15:38

Что-то мне кажется, что все это отдает то ли заумностью, то ли бредом.

Что мешает отдать с сервера коллекции с идентефикаторами? А на клиенте сортировать с помощью Sort и вытаскивать объект по идентефикатору? Если таки это сложно - "множество ArrayCollection соответствующих таблицам серверной БД", то все равно отдавать с сервера коллекцию DTO, в которую уже будут всунуты данные с разных таблиц и назначены идентефикаторы для предоставления уникального доступа. Мудрить с двумя структурами на клиенте - на кой?

Кроме этого - коллекция с сервера отдается в зависимости от построения списка на сервере (допустим, ArrayList и LinkedList дадут/могут дать разный порядок), однако при формировании объекта ArrayCollection в его свойстве source типа Array порядок вложенных объектов будет постоянен вне зависимости от показываемой сортировки. По крайней мере, это может избавить от создания параллельной структуры для коллекции.

zorexundra 12.09.2011 15:48

Цитата:

Сообщение от Dimitry_II (Сообщение 1030648)
Что мешает отдать с сервера коллекции с идентефикаторами? А на клиенте сортировать с помощью Sort и вытаскивать объект по идентефикатору?

А можно какой-нибудь простенький пример кода?
Среда разработки - Flex-AMFPHP-MySQL.

Добавлено через 23 минуты
Цитата:

Сообщение от saprahan (Сообщение 1030647)
Можно, например, экстендить ArrayCollection, добавить параметр itemsMap, и в конструкторе ArrayCollection'a (а также, возможно в оверрайде метода refresh) прописать инициализацию мапы из сорса

Если при разработке конечных приложений используются принципы ООП, то возможно была выбрана не та IDE :)
Можно, также, пример кода?
Сама по себе идея, на мой взгляд, интересная.

saprahan 12.09.2011 16:46

Цитата:

Сообщение от zorexundra (Сообщение 1030657)
А можно какой-нибудь простенький пример кода?
Среда разработки - Flex-AMFPHP-MySQL.

Добавлено через 23 минуты

Если при разработке конечных приложений используются принципы ООП, то возможно была выбрана не та IDE :)
Можно, также, пример кода?
Сама по себе идея, на мой взгляд, интересная.

Интересно, при чем здесь IDE ?

Добавлено через 3 минуты
Очень здравая идея с построением общей мапы есть в HierarchicalCollectionView.Регулярно проходить про древовидной структуре и вправду дорого - цикл в цикле. Там как раз и строится мапа как хелпер. Правда лишь для открытых нод, что на практике несет в себе мало пользы.

zorexundra 12.09.2011 16:59

saprahan, это шутка в ответ на предложение дорабатывать исходные объекты.
Поделитесь мнением.
Предположим есть экземпляр пользовательского класса MappedArrayCollection расширяющий ArrayCollection.
Экземпляр слушает событие "collectionChange". По этому событию MappedArrayCollection циклом for each перебирает все элементы массива source и присваивает им идентификаторы. MappedArrayCollection имеет публичный метод отдающий элемент source по внешнему запросу с параметром идентификатора.
В source 30000 элементов. Для каждого элемента в MappedArrayCollection задаётся 10 переменных со значением ключа-идентификатора. Насколько быстрым будет этот класс? Не повесит-ли он приложение?
Не проще-ли создать отдельную хеш-таблицу со ссылками на элементы ArrayCollection.source?

saprahan 13.09.2011 14:40

Цитата:

Сообщение от zorexundra (Сообщение 1030704)
saprahan, это шутка в ответ на предложение дорабатывать исходные объекты.
Поделитесь мнением.
Предположим есть экземпляр пользовательского класса MappedArrayCollection расширяющий ArrayCollection.
Экземпляр слушает событие "collectionChange". По этому событию MappedArrayCollection циклом for each перебирает все элементы массива source и присваивает им идентификаторы. MappedArrayCollection имеет публичный метод отдающий элемент source по внешнему запросу с параметром идентификатора.
В source 30000 элементов. Для каждого элемента в MappedArrayCollection задаётся 10 переменных со значением ключа-идентификатора. Насколько быстрым будет этот класс? Не повесит-ли он приложение?
Не проще-ли создать отдельную хеш-таблицу со ссылками на элементы ArrayCollection.source?

Я вам это и написал, читайте внимательно. Слушать эвент и что то по нему делать - это вы уже придумали сами ))) ROFL

BTW экстендить нативные FLEX компоненты при более-менее сложной разработке приходится регулярно. Не стоит этого пугаться.

zorexundra 13.09.2011 17:50

saprahan, представьте, на станции авто-техобслуживания механик говорит Вам:
- Ща доработаем вашу колымагу! :)
Вот набросал. Что скажите?:
Код AS3:

package
{
        import mx.collections.ArrayCollection;
        import mx.events.CollectionEvent;
        public class MappedArrayCollection extends ArrayCollection
        {
                public var arrayElement:Object = new Object();
                public function MappedArrayCollection(source:Array=null)
                {
                        super(source);
                        addEventListener(CollectionEvent.COLLECTION_CHANGE, collectionChangeHandler);
                }
                override public function set source(s:Array):void
                {
                        super.source = s;
                        for each(var el:Object in s){
                                arrayElement["e"+el.ID]=el;
                        }
                }
                private function collectionChangeHandler(event:CollectionEvent):void
                {
                        switch(event.kind){
                                case "add":
                                        arrayElement["e"+event.items[0].ID]=event.items[0];
                                        break;
                                case "remove":
                                        delete arrayElement["e"+event.items[0].ID];
                                        break;
                        }
                }
        }
}



Часовой пояс GMT +4, время: 08:28.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.