Форум 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=183128)

koIIImarik 13.08.2012 01:35

Очень «строгая» проверка объектов
 
Всем привет)

Появилась необходимость в сравнении 2 объектов на полную идентичность, т.е. на то, что они ссылаются на один и тот же фрагмент в памяти. Не знаю, возможно ли такое в AS3, но постараюсь объяснить, как это должно работать:

Код AS3:

// Задаём начальные данные
var obj1:Object = { prop: 1 };
var obj2:Object = { prop: 1 };
var obj3:Object = { prop: obj1.prop };
 
// Тут функция должна возвращать false
checkObjectsIdentity(obj1.prop, obj2.prop)
// Тут функция должна возвращать true
checkObjectsIdentity(obj1.prop, obj3.prop)
 
/**
 * Функция, которая должна проверять объекты на идентичность
 * (ссылание на 1 объект в памяти).
 *
 * @param        object1
 * @param        object2
 *
 * @return
 */

function checkObjectsIdentity(object1:*, object2:*):Boolean
{
        // Тут происходит магия
}

Как мне подсказывает интуиция, из-за того, что в AS3 при работе с простыми объектами (Boolean, Sting, Number и т.п.) происходит копирование объекта данных, а не ссылка на его изначальный объект, подобная проверка вообще будет невозможна, так как мы всегда будем ссылаться на разные участки памяти (так как при присваивании объекту свойства другого объекта с простым типом данных происходит его копирование).

Но всё-таки, возможно, кто-то сталкивался с подобной задачей и сможет подсказать решение.

За ранее спасибо)

Wolsh 13.08.2012 02:11

Цитата:

Появилась необходимость в сравнении 2 объектов на полную идентичность
1 это не объект. Это же простой тип, он передается по значению, а не по ссылке.
Другими словами, Вы хотите сравнивать переменные, то есть ссылки. Но Ваша функция не получает ссылок. Она получает просто значения — единички. И эти значения никак не могут быть неравны.

Добавлено через 12 минут
Не говоря уже о том, что prop в obj3 вовсе не собирается хранить ссылку на obj1 и его prop, а просто сохраняет значение:
Код AS3:

var obj1:Object = { prop: 1 };
var obj2:Object = { prop: 1 };
var obj3:Object = { prop: obj1.prop };
obj1.prop = 5;
trace(obj3.prop); // output: 1

Добавлено через 17 минут
Решение для первого случая — передавать ссылки на объекты и строковые имена ключей. В функции сравнивать И объекты, и значения ключей
Код AS3:

function checkObjectsIdentity(object1:*, propName1:String, object2:*, propName2:String):Boolean
{
        // Тут происходит магия
        return object1 === object2 && object1[propName1] === object2[propName2];
}

Но для второго случая true не будет из-за неравенства объектов.

Добавлено через 23 минуты
Да и в первом случае все не так гладко)) Мы получим true при таком раскладе:
Код AS3:

var obj1:Object = { prop: 1, prop2: 1 };
// Тут функция должна возвращать false
checkObjectsIdentity(obj1, "prop", obj1, "prop2");


mikhailk 13.08.2012 13:04

Цитата:

Появилась необходимость в сравнении 2 объектов на полную идентичность
Думаю, если бы Вы сообщили, в связи с чем появилась потребность в решении такой нетривиальной задачи, Вам бы подсказали, как этого избежать.

А что касается "магии", то она очень проста. Пишете контрольный перечень свойств объекта-1 и меняете их по определенному правилу, если у объекта-2 они так же изменились - значит да, это один объект. Потом свойства откручиваете в состояние до проверки. Но на мой взгляд это костыль. Типа, если телега доехала до моста, проверяем, есть ли у нее колеса, если колес нет, ставим дефолтные.

mayakwd 13.08.2012 13:18

ObjectUtil.compare

Bgg 13.08.2012 13:36

Есть ещё один способ, он странный и довольно медленный. :)
Код AS3:

var o0:Object = {a:1};
var o1:Object = {a:1};
trace(getHashCode(o0) === getHashCode(o1));//false
trace(getHashCode(o0));//@11d7fd49
trace(getHashCode(o1));//@11d7fd61
 
function getHashCode(obj:Object):String{
 
        var result:String = '';
 
        if(obj){
                try {
                  System(obj);
                }
                catch (e:Error) {
                  result = String(e).replace(/.*([@|\$].*?) в .*$/gi, '$1');
 
                  if(result.length > 20){
                    result = String(e).replace(/.*([@|\$].*?) to .*$/gi, '$1');
                  }
                }
        }else{
                result = 'null';
        }
 
        return result;
}

Ну и да, работает только в русской и английской локали, мне больше не нужно было.


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

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