Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Вопрос про доступ к свойствам объектов, или ассоциативные массивы (http://www.flasher.ru/forum/showthread.php?t=188246)

Ленок 30.11.2012 22:45

Вопрос про доступ к свойствам объектов, или ассоциативные массивы
 
Привет!

Как облегчить такую конструкцию?

Код AS3:

        // name = 'some.where.in.galactic'
                        // stack:Object {ой блин....}
 
                        var fragments:Array = name.split('.');
                        switch (fragments.length)
                        {
                                case 1:
                                        return stack[name];
                                        break;
                                case 2:
                                        return stack[fragments[0]][fragments[1]];
                                        break;
                                case 3:
                                        return stack[fragments[0]][fragments[1]][fragments[2]];
                                        break;
                                case 4:
                                        return stack[fragments[0]][fragments[1]][fragments[2]][fragments[3]];
                                        break;
                                case 5:
                                        return stack[fragments[0]][fragments[1]][fragments[2]][fragments[3]][fragments[4]];
                                        break;
                                case 6:
                                        return stack[fragments[0]][fragments[1]][fragments[2]][fragments[3]][fragments[4]][fragments[5]];
                                        break;
                        }


GBee 30.11.2012 23:10

Nмерный массив это круто, а смысл (задача какая)?

Ленок 30.11.2012 23:22

Приходят данные произвольной структуры, надо с ними работать.

А в AS3 нет средств, позволяющих лаконично написать такой код? Надо сделать сеттер и геттер. Первый получает ключ массива произвольной глубины (land.town.tower.room...) и значение, создает указанный элемент. Второй получает ключ, и возвращает значение по нему.

Как указывать на элементы объекта?


Страшный сеттер

Код AS3:

var fragments:Array = name.split('.');
                        if (fragments.length == 1)
                        {
                                stack[name] = value;
                        }
                        if ((stack[fragments[0]] == undefined) && (fragments.length > 1))
                        {
                                stack[fragments[0]] = {};
                        }
                        if ((stack[fragments[1]] == undefined) && (fragments.length > 2))
                        {
                                stack[fragments[0]][fragments[1]] = {};
                        }
                        if ((stack[fragments[2]] == undefined) && (fragments.length > 3))
                        {
                                stack[fragments[0]][fragments[1]][fragments[2]] = {};
                        }
                        switch (fragments.length)
                        {
                                case 2:
                                        stack[fragments[0]][fragments[1]] = value;
                                        break;
                                case 3:
                                        stack[fragments[0]][fragments[1][fragments[2]] = value;
                                        break;
                                case 4:
                                        stack[fragments[0]][fragments[1][fragments[2]][fragments[3]] = value;
                                        break;
                        }

И что? Неужели это должно быть именно так ужасно?

GBee 30.11.2012 23:38

Хеш?

Код AS3:

private var _hash:Object = {};
_hash[name] = 'value';
 
...
 
return _hash[name];


Ленок 30.11.2012 23:41

Хеш. Но вот так не работает:

Код AS3:

key = 'one.two.three.four.five';
value = 'Sun';
stack[key] = value;
return stack.one.two.three.four.five; // не работает

Предполагаю, что stack['one.two.three.four.five'] это не то же, что stack.one.two.three.four.five

Коллеги, можете проверить?

GBee 30.11.2012 23:43

stack['one.two.three.four.five'] то же самое что и stack[key]

return stack['one.two.three.four.five'] только так.

Добавлено через 1 минуту
stack.one.two.three.four.five это какой-то динамический ад.

Ленок 30.11.2012 23:51

Код AS3:

stack['one.two.three.four.a'] = 'A';
stack['one.two.three.four.b'] = 'B';

one.two.three.four - существует и содержит {a:'A',b:'B'} ?

for each (letter in one.two.three.four) - будет работать?

GBee 30.11.2012 23:54

Цитата:

one.two.three.four - существует и содержит {a:'A',b:'B'} ?

for each (letter in one.two.three.four) - будет работать?
нет
нет

udaaff 30.11.2012 23:54

Не будет.

GBee 30.11.2012 23:56

если я начал понимать вашу задачу, то вам нужна рекурсия.

Ленок 30.11.2012 23:59

Спасиб :)

А как внутри рекурсивного метода создавать ссылку на объект?

GBee 01.12.2012 00:08

1) Создаете корень,
2) Отдаете внутрь рекурсии корень и нейм.
3) В рекурсии выцепляете имя до первой точки.
4) У переданного корня создаете параметр с таким именем и пихаете в него новый объект.
5) Отдаете созданный объект внутрь рекурсии и остаток от нейма.
6) Переходите в 3 пункт //точнее уже не вы.

Повторяете 2-6 для всех неймов. Корень один.

Добавлено через 53 секунды
а! Объект должен быть динамический. И еще значение пихать надо.

Ленок 01.12.2012 00:12

ОЗУ скушает :(

А ссылки на объекты можно создавать? Плохо представляю, как сделать иначе.

GBee 01.12.2012 00:16

Рано вы об ОЗУ думаете. Если у вас есть объект (не "простой" String, int и т.д.), то значит у вас есть ссылка на него.

Ленок 01.12.2012 00:24

Если честно, плохо представляю, как ссылаться на такой объект.

GBee 01.12.2012 00:26

Вы пространные вопросы задаете. Я даже не могу связать с задачей в первом сообщении.
var o:Object = new Object();
о - ссылка на объект.

etc 01.12.2012 01:33

Код AS3:

var fragments:Array = name.split('.');
var source:Object = stack;
while (fragments.length) {
  var current:String = fragments.shift();
  if (current in source) source = source[current];
}
return source;

Допилите по месту.

Ленок 01.12.2012 01:52

Простите, не туда...

Korchy 01.12.2012 09:50

2 Ленок

Я бы попробовал данные свести к XML структуре. То что вы пытаетесь обработать очень похоже на простейшее дерево.

Wolsh 01.12.2012 11:17

Цитата:

Простите, не туда...
Код AS3:

if (!current in source) source[current] = {};
source = source[current];

?

Psycho Tiger 01.12.2012 12:28

Код AS3:

if (!current in source)

! сильнее.
Надо так:
Код AS3:

if (!(current in source))

@etc, лучше без условия. Если кривые входные данные – лучше RTE схватить, чем пропустить пару current и залезть в не тот индекс.

etc 01.12.2012 14:12

Ну проще throw new ArgumentError в else запихать.

Ленок 01.12.2012 14:55

Цитата:

Сообщение от etc (Сообщение 1107148)
Код AS3:

var fragments:Array = name.split('.');
var source:Object = stack;
while (fragments.length) {
  var current:String = fragments.shift();
  if (current in source) source = source[current];
}
return source;

Допилите по месту.

Работает великолепно, без допиливания.

А как сделать сеттер? Может быть у кого-нибудь есть идеи?

wvxvw 01.12.2012 23:18

А он вам так нужен, сеттер? Вызов функции столько же места занимает:
foo.bar = 100;
foo.bar(100);

Ленок 02.12.2012 01:03

Цитата:

Сообщение от wvxvw (Сообщение 1107303)
А он вам так нужен, сеттер? Вызов функции столько же места занимает:
foo.bar = 100;
foo.bar(100);

Круто, что уж :)

Код AS3:

foos.bars.foo.bar = 1; // сработает?
foos.bars.foo.foo = 1;

И на закуску

Код AS3:

for (index in foos.bars.foo)

Что сделает после вышеуказанного? :)

Мне надо, чтобы итерировал. С костылями в начале темы и с удачным геттером все нормально. Осталось придумать сеттер.

wvxvw 02.12.2012 01:55

Зачем вам именно в таком формате? Если вы не можете зарание планировать, и вам так сильно хочется чтобы именно сеттер: есть Proxy класс, в котором вы можете реализовать себе такое. Ну только, пока будете реализовывать прийдет понимание, что проще было без него, функциями ограничится. Но дело ваше.

Т.е. реализовывая это в Proxy вы поймете, что обращение к такому свойству сопряжено с кучей накладных расходов (за динамику нужно платить), и что в итоге схема типа object.set(value, ...fieldConsituents); get / find / each вам будет дешевле организовать, чтем воплотить в жизнь интерфейс, в котором еще и свои баги есть.

Ленок 02.12.2012 17:23

От сервера приходят данные - игровой мир. Он в доску динамичен. Сервер присылает его по частям, в зависимости от ситуации и местоположения. Клиент, соответственно, его отрабатывает.

Формат предусматривает как произвольные данные в строковом формате, ассоциативные массивы, а также колбеки. Некоторые условно произвольные фрагменты данных необходимо итерировать для обработки на клиенте.

Клиент в процессе работы дополняет копию этих данных, изменяет и удаляет... Короче, делает полноценный CRUD. Часть из них еще и возвращает.

Как это решено сейчас.
1. Такое решение было применено в прототипе. Формирование данных в нужной структуре полностью на сервере. Когда клиенту нужно изменить что-то в данных - он просит об этом сервер. Добрый PHP делает, что просили, и посылает пачку обновленных данных. Клиент кушает присланное.
2. Решение, примененное в альфе - в начале этой темы.

Оба решения работают. Не нравится: а. Костыли, б. Ограничения.

По геттеру решение найдено, и оно уже прошло проверку боем. Осталось придумать сеттер. В AS не сильна, только что начала его изучать, простите :)


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

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