|
|
|||||
[+4 06.05.14]
|
множественный перебор
Всем привет.
Вот интересно, как обычно справляются с большим кол-ом циклов на однотипных условиях. Приведу пример о чем я. Имеется вектор CustomSprite . Стоит задача - проверить, изменил ли координату хоть один из набора - и сделать что - то Ок, теперь предположим, что задач несколько аля for( i = 0; i < v.length; i++) if( v[i].x > 30 ) doSomthing1() for( i = 0; i < v.length; i++) if( v[i].y > 40 ) doSomthing2() for( i = 0; i < v.length; i++) if( v[i].visible ) doSomthing3() Какним нибудь P.s. в данном случае пример неочень ибо его как раз можно в один пихнуть, но думаю смысл всем понятен
__________________
Марк Tween |
|
|||||
Как вариант можно подписать каждый объект на событие Event.CHANGE (Или на какое-нибудь свое MyLittleSprite.CHANGED_COORDINATES) и сделать обработчик события в одном месте, например в объекте-родителе ваших спрайтов. При изменении координат любого объекта производить диспетчиризацию события Event.CHANGE, на которое вы собственно и подписали объект, и обрабатывать это событие во внешнем обработчике. Тогда не будет никаких циклов.
На несколько задач вопрос решается аналогично - в зависимости от изменения диспетчиризуем одно, второе или третье событие. Или одно и то же событие, но с разными параметрами Вариант с одним событием: ... //Там, где у вас добавляются CustomSprite в вектор: public function generateSprites():void { for(var i:uint = 0; i < 30; i++) { var myLittleCustomSprite:CustomSprite = new CustomSprite(); myLittleCustomSprite.addEventListener(Event.CHANGE, somethingHappened); customSpriteVector.push(myLittleCustomSprite); } } public function somethingHappened(e:Event):void { trace("Изменились координаты или того хуже"); } ... /** * В вашем классе CustomSprite */ public function changedSomething():void { dispatchEvent(new Event(Event.CHANGE)); } public class MyCustomEvent extends Event { public MyCustomEvent(type:String, changeTracker:String , bubbles:Boolean = false, cancelable:Boolean = false) } ... //Там, где у вас добавляются CustomSprite в вектор: public function generateSprites():void { for(var i:uint = 0; i < 30; i++) { var myLittleCustomSprite:CustomSprite = new CustomSprite(); myLittleCustomSprite.addEventListener(Event.CHANGE, somethingHappened); customSpriteVector.push(myLittleCustomSprite); } } public function somethingHappened(e:Event):void { var receivedEvent = e as MyCustomEvent; switch(receivedEvent.changeTracker) { case "changedX": trace("Изменился Х"); break; case "changedY": trace("Изменился Y"); break; case "changedVisibility": trace("Изменился visibility"); break; } } ... /** * В вашем классе CustomSprite */ public function changedSomething(changed:String):void { dispatchEvent(new MyCustomEvent(Event.CHANGE, changed)); } Последний раз редактировалось KumoKairo; 01.08.2013 в 08:37. |
|
|||||
[+4 06.05.14]
|
KumoKairo - вообще меня не понял. События тут вообще не причем. Это я просто предоставил пример насчет координат, тут совсем разговор о другом.
Расширю пример : есть несколько стадий игры, начало, конец, в игре*. Некий объект меняет свои характеристики в течении цикла. И по окончанию игры нужно проводить действия. Все записало в модель, все держится, объектов куча поэтому проверяем в цикле. И вот к пример где мне пришлось делать 2 цикла с однотипными условиями так скажем : 1) Записали текущее состояние стола в модель 2) Проверяем в цикле - если хоть один объект *сделал что-то* - очищаем из модели тек. состояние 3) Проверяем в цикле - если хоть один объект *сделал что-то* - записываем то, что он сделал. P.s. модель общая Ну вот не нравится мне такая запись, из рассчета того, что можно и до 3х-4х циклов увеличить из за некоторых условий
__________________
Марк Tween |
|
|||||
Можно использовать временные хранилища ( так же и для остальных примеров, создаем временные массивы после цикла переприсвоение)
__________________
return this... |
|
|||||
Цитата:
Кстати, почему сразу не писать: for each (var vi:V in v){ if(vi.isBetting) model.clear(); break; } for each (var vi:V in v){ if(vi.isBetting) model.arr.push(vi.data); } Тут нет никакой избыточной информации, короче не напишешь, и функции высших порядков тут лучше не сделают (можно, конечно, слепить массив функций-итераторов и упомянуть v только один раз - но это абзац и код короче не делает), вы же кроме "пройтись по v" никакой логики не дублируете, или таки что-то есть ещё? В чём проблема то? |
|
|||||
Регистрация: Nov 2010
Сообщений: 497
|
Да никак обычно в AS3 с этим не справляются. И проблема даже не столько в необходимости методов, сколько в очень длинном синтаксисе создания анонимных функций. Если бы не это, можно было бы писать в функциональном стиле:
v. filter(function(item : Object, idx: int, array : Arr) : Boolean { return item.x > 30;}). forEach(function((item : Object, idx: int, array : Arr) : void { doSomething1(); }); if (v.some(function(item : Object, idx: int, array : Arr) : Boolean { return item.isBetting; })) model.clear(); Если создадите свою функцию, станет легче, но не сильно. Да, прототипы функций будут короче, но само объявление функции - длинное. Под платформу flash мне нечего вам посоветовать. Есть haxe, но там лямбды (анонимные функции) тоже начинаются со слова function. А вот в функциональных языках все хорошо. Например, scala: В других функциональных языках (вроде разновидностей ml и lisp'ов) все будет то же с точностью до синтаксиса/названия методов. Даже в haskell'е будет почти так же (ну с точностью до монад, конечно же). |
Часовой пояс GMT +4, время: 06:04. |
|
« Предыдущая тема | Следующая тема » |
Опции темы | |
Опции просмотра | |
|
|