Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Вопрос по проверке Properties`ов - Object типа. (http://www.flasher.ru/forum/showthread.php?t=169374)

ERrorMAKros 03.10.2011 22:39

Вопрос по проверке Properties`ов - Object типа.
 
Добрый день,
существует Object (к примеру) такого вида:
Код:

var dataset:Object = {
        one: "1",
        two: "2",
        sub: {
                bool: true,
                dataset: {
                        value_to_check: "someValue"
                }
        }
};

Вопрос в следующем: подскажите пожалуйста какой нибудь удобный способ проверить существование ветки dataset.sub.dataset.value_to_check.
К примеру:
Код AS3:

if(dataset) {
        if(dataset.sub) {
                if( dataset.sub.dataset ) {
                        if (dataset.sub.dataset.value_to_check) {
                                trace(true); // ветка: dataset.sub.dataset.value_to_check
                        }
                }
        }
}

...такой способ страшно долгий и на мой взгляд не практичный, можно ли данное выражение лексически описать максимально короче (имеется в виду - as3 кодом)?

КорДум 03.10.2011 22:43

Код AS3:

if (!dataset) return;
if (!dataset.sub) return;
if (!dataset.sub.dataset ) return;
if (!dataset.sub.dataset.value_to_check) return;
trace(true); // ветка: dataset.sub.dataset.value_to_check

=)

Добавлено через 1 минуту
Код AS3:

if (dataset && dataset.sub && dataset.sub.dataset &&
    dataset.sub.dataset.value_to_check) {
        trace(true); // ветка: dataset.sub.dataset.value_to_check
}

Хех.

ERrorMAKros 03.10.2011 22:57

Спасибо.

Inet_PC 03.10.2011 23:06

Код AS3:

public function getProperty(obj: Object, property: String):*
{
        if (obj != null && property != null && property != '')
        {
                var value: *;
                var prop : String;
                var props: Array = property.split('[').join('.').split(']').join('.').split('.');
 
                while (props.length > 0)
                {
                        prop = props.shift();
                        if (obj && prop && prop in obj)
                        {
                                value = obj[prop];
                                obj  = value;
                        }
                }
                return value;
        }
        return null;
}
var value:Object = getProperty(dataset, 'dataset.sub.dataset.value_to_check');

Или даже так (для примера):
Код AS3:

var user: Object = getProperty(r.data, 'allUsers[0].arena1.usersList.mainUser');

А вообще нетипизированный доступ - это очень и очень плохо!

Psycho Tiger 03.10.2011 23:10

Для проверки существования нужно использовать оператор in.
Вообще через try можно, но не люблю я такие штуки.
Можно написать свой метод getValue, в который передавать строковую переменную. - в примере "dataset.sub.dataset.value_to_check".

Меня как всегда опередили =(

Inet_PC 03.10.2011 23:16

try/catch тормозит, так что зря-понапрасну лучше не использовать

Psycho Tiger 03.10.2011 23:30

Ты не прав, бро.
Код AS3:

                        var hash:Object = { obj: { obj: { value: 5 } } };
                        trace(hash.obj.obj.value);
                        var i:int;
                        var count:int = 1000000;
                        var value:int;
                        var startTime:int;
 
                        startTime = getTimer();
                        i = count;
                        while (i--) {
                                try {
                                        value = hash.obj.obj.value;
                                }
                                catch (error:Error) {
 
                                }
                        }
                        trace("Hit try: ", (getTimer() - startTime));
 
                        startTime = getTimer();
                        i = count;
                        while (i--) {
                                try {
                                        value = hash.obj.noObject.value;
                                }
                                catch (error:Error) {
 
                                }
                        }
                        trace("Miss try: ", (getTimer() - startTime));
 
                        startTime = getTimer();
                        i = count;
                        while (i--) {
                                value = getProperty(hash, "obj.obj.value");
                        }
                        trace("Hit getProperty: ", (getTimer() - startTime));
 
                        startTime = getTimer();
                        i = count;
                        while (i--) {
                                value = getProperty(hash, "obj.noObject.value");
                        }
                        trace("Miss getProperty: ", (getTimer() - startTime));

Код:

Hit try:  213
Miss try:  9182
Hit getProperty:  7639
Miss getProperty:  9738

К тому же, твой getProperty возвращает null если объект не найден. А если он найден, но его значение - null?

Inet_PC 04.10.2011 01:31

Говоря о "тормознутости" try/catch я имел ввиду общий случай, а не этот конкретно. Результаты теста у меня идентичны Вашим, но опять таки, немного наигран тест, если чуток его изменить, то try/catch нервно курит в сторонке((

Код AS3:

var hash:Object = { obj: { obj: { value: 5 } } };
                        trace(hash.obj.obj.value);
                        var i:int;
                        var count:int = 1000000;
                        var value:int;
                        var startTime:int;
 
                        startTime = getTimer();
                        i = count;
                        while (i--) {
                                try {
                                        value = hash.obj.obj.value;
                                }
                                catch (error:Error) {
 
                                }
                        }
                        trace("Hit try: ", (getTimer() - startTime));
 
                        startTime = getTimer();
                        i = count;
                        while (i--) {
                                try {
                                        value = hash.obj.obj.value.prop;
                                }
                                catch (error:Error) {
 
                                }
                        }
                        trace("Miss try: ", (getTimer() - startTime));
 
                        startTime = getTimer();
                        i = count;
                        while (i--) {
                                value = getProperty(hash, "obj.obj.value");
                        }
                        trace("Hit getProperty: ", (getTimer() - startTime));
 
                        startTime = getTimer();
                        i = count;
                        while (i--) {
                                value = getProperty(hash, "obj.obj.value.prop");
                        }
                        trace("Miss getProperty: ", (getTimer() - startTime));

Hit try: 221
Miss try: 13299
Hit getProperty: 8104
Miss getProperty: 8987

А у Вас такие же результаты? Или я что-то не так делаю? Да, получается, что метод то себя не оправдал, а жаль((

Psycho Tiger 04.10.2011 01:47

Нельзя говорить о "нервно курит в сторонке", пока один из параметров (который, кстати, должен доминировать: чаще отсутствие поля это исключительный случай, а не наоборот) работает в 40 раз быстрее =)

try/catch мне не нравится тем, что в строчке кода, которую я в него оберну, может содержаться совершенно другое RTE. Я стараюсь не использовать его вообще нигде. Поэтому идеологически твой вариант мне ближе, но я бы реализовал его по другому: getProperty возвращает Boolean, удалось считать ли, а сам getProperty записывает в поле считанное значение.
Т.е.
Код AS3:

if (Props.getProperty("hash.value.value")) myValue=Props.value;

Проблема с двойственностью толкования null исчезнет и исчезнет геморрой по повторному вбиванию длинного пути до хэша (первый раз для проверки, второй раз для присваивания).

Inet_PC 04.10.2011 01:48

А если так:
Код AS3:

var hash:Object = { obj: { obj: { value: 5 } } };
                        trace(hash.obj.obj.value);
                        var i:int;
                        var count:int = 1000000;
                        var value:int;
                        var startTime:int;
 
                        var props: Array;
 
                        startTime = getTimer();
                        i = count;
                        while (i--) {
                                try {
                                        value = hash.obj.obj.value;
                                }
                                catch (error:Error) {
 
                                }
                        }
                        trace("Hit try: ", (getTimer() - startTime));
 
                        startTime = getTimer();
                        i = count;
                        while (i--) {
                                try {
                                value = hash.obj.obj.value.prop;
                                }
                                catch (error:Error) {
 
                                }
                        }
                        trace("Miss try: ", (getTimer() - startTime));
 
                        startTime = getTimer();
                        i = count;
                        props = ('obj.obj.value').split('[').join('.').split(']').join('.').split('.');
                        while (i--) {
                                value = getProperty(hash, "obj.obj.value", props);
                        }
                        trace("Hit getProperty: ", (getTimer() - startTime));
 
                        startTime = getTimer();
                        i = count;
                        props = ('obj.obj.value.prop').split('[').join('.').split(']').join('.').split('.');
                        while (i--) {
                                value = getProperty(this, "obj.obj.value.prop", props);
                        }
                        trace("Miss getProperty: ", (getTimer() - startTime));

То:
Hit try: 234
Miss try: 13595
Hit getProperty: 627
Miss getProperty: 695

В общем производительность оценить в AS3 на глаз (и даже такими синтетическими тестами) нереально, слишком много факторов не учитывается. Я возможно заменю "внутренности" getProperty на try/catch. Пока в раздумьях, просто я придерживаюсь мнения, что там где можно обойтись без ловли ошибок, нужно обходится...

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

try/catch мне не нравится тем, что в строчке кода, которую я в него оберну, может содержаться совершенно другое RTE.
Совершенно с Вами согласен

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

Я стараюсь не использовать его вообще нигде
Аналогично, согласен

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

Код AS3:

if (Props.getProperty("hash.value.value")) myValue=Props.value;


Такая запись затрудняет чтение. А вот так ли часто нужно знать если свойство, если его значение null?

Добавлено через 5 минут
Ну в общем я за производительность обеями ногами, как говорится копейка Гигагерц бережет)


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

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