ActionScript Сравнение массивов - PullRequest
4 голосов
/ 23 мая 2010

как я могу оценить, равен ли мой тестовый массив моей статической константе DEFAULT_ARRAY? мой вывод не должен возвращать истину?

public class myClass extends Sprite
{
private static const DEFAULT_ARRAY:Array = new Array(1, 2, 3);

public function myClass()
{
var test:Array = new Array(1, 2, 3);
trace (test == DEFAULT_ARRAY);
}

//traces false

Ответы [ 3 ]

8 голосов
/ 23 мая 2010

Маке уже указал на проблему. Оператор == сообщит вам (для ссылочных типов, таких как объекты Array), если две переменные указывают на один и тот же объект. Это явно не тот случай. У вас есть 2 разных объекта, которые имеют одинаковый контент.

Итак, вы, вероятно, ищете способ сравнить, имеют ли 2 массива одинаковое содержимое. Эта, казалось бы, простая задача может оказаться сложнее, чем кажется.

Стандартным способом является использование такой функции:

function areEqual(a:Array,b:Array):Boolean {
    if(a.length != b.length) {
        return false;
    }
    var len:int = a.length;
    for(var i:int = 0; i < len; i++) {
        if(a[i] !== b[i]) {
            return false;
        }
    }
    return true;
}

Это будет работать в некоторых (возможно, в большинстве) случаях. Но произойдет сбой, если элементы в любом из массивов имеют семантику ссылочного типа (в отличие от семантики типа значения). В основном, числа (включая целые числа и числа), строки, логические, нулевые и неопределенные имеют семантику типа значения:

Дано:

var a:int = 0;
var b:int = 0;

Это будет справедливо:

trace(a == b);

Для всего остального сравнение с == вернет true, только если обе переменные ссылаются на один и тот же объект:

var a:Object = {data:1};
var b:Object = {data:1};

trace(a == b); // false

Но

var a:Object = {data:1};
var b:Object = a;

trace(a == b); // true

Итак, если ваши массивы содержат объекты (или, в свою очередь, другие массивы), areEqual завершится ошибкой в ​​этом случае:

var arr_1:Array = [{data:1}];
var arr_2:Array = [{data:1}];

trace(areEqual(arr_1,arr_2));

Почему? Поскольку объект {data:1}, который вы сохранили в arr_1, отличается от объекта {data:1}, хранящегося в arr_2.

Я не думаю, что возможно создать универсальную функцию, которая рекурсивно проверяет, равны ли содержимое двух массивов, потому что нет общего способа определить, следует ли считать два объекта равными. Это действительно зависит от ваших объектов, вашего домена и т. Д. в вашем приложении два объекта следует считать равными, если они имеют одинаковое ìd (при условии, что вы определили свойство ìd). Как я думаю, это показывает, что нет способа узнать заранее, что делает объекты равными.

3 голосов
/ 11 февраля 2013

Чувак, используй mx.utils.ObjectUtil ... создатели actioncript уже подумали об этом.

ObjectUtil.compare(this.instructions, other.instructions) == 0;
2 голосов
/ 23 мая 2010

То, что вы делаете, сравнивает ссылки, а не значения. Это потому, что массив не является типом значения. Например, число - это тип значения. Число со значением 3 всегда будет равно 3, независимо от того, какие ссылки вы сравниваете. Но ссылочный тип, блок памяти, доступ к которому осуществляется по ссылке, - это просто блок памяти. Если у вас есть две ссылки на один и тот же блок, они будут считаться равными. Но опять же, вы действительно просто сравниваете ссылки, а не фактические значения.

В вашем случае ваше условие будет истинным, если у вас будет следующий код:

private static const DEFAULT_ARRAY:Array = new Array(1, 2, 3);

public function myClass()
{
    var test:Array = DEFAULT_ARRAY;
    trace (test == DEFAULT_ARRAY);
}

//traces true

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

private static const DEFAULT_ARRAY:Array = new Array(1, 2, 3);

public function myClass()
{
    var test:Array = new Array(1, 2, 3);

    var isEqual:Boolean = true;

    for (var i:int = 0; i < test.length; i++)
    {
        if (test[i] == DEFAULT_ARRAY[i])
            continue;
        else
        {
            isEqual = false;
            break;
        }
    }

    trace (isEqual);
}

//traces true

Hamcrest может быть полезен в этих типах сценариев.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...