PDA

Просмотр полной версии : Как получить копию массива?


SiDDD
15.10.2006, 22:59
Всем драсти!

У меня такая проблема - отчегото не получается скопировать Array a1 в a3. Вместо копирования выходит что a3 содержит указатели на а1 и все изменения в а3 меняют и родича а1 (но необходимо чтоб а1 оставался нетронут)... Должно сразу сказать, что с одномерным массивом всё исправно работает! Как "выход" испробовал копирование каждого "этажа" массива с помощью FOR, но ведь это не выход.. Хотелось бы знать - возможно ли это организовать без трех страниц кода??? Всего то и хотелось бы получить копию одного МНОГОМЕРНОГО массива.

Код, что не катит (15485):
var i:Number=0;
var a1:Array = [[1,2,3,4,5,6,7,8,9],[1,2,3,4,5,6,7,8,9]];
var a3:Array = new Array();

_root.onEnterFrame=function(){

a3=a1.concat();
myTest();
txt1.text=a1;
txt2.text=a3;
};

function myTest(){

a3[0][i]=333;
i++;
if(i==9) i=0;
};

Далее код который работает, но...но если у меня массив из 100 "этажей"? При 50 FPS! Ужас...
var i:Number=0;
var a1:Array = [[1,2,3,4,5,6,7,8,9],[1,2,3,4,5,6,7,8,9]];
var a2:Array = new Array();
var a2:Array = new Array();
var a3:Array = new Array();

_root.onEnterFrame=function(){

a3=a2.concat(a1);
a3[0]=a2.concat(a1[0]); // адын этаж
a3[1]=a2.concat(a1[1]); // два... и так до 100!! Можно FOR использовать - но нельзя ли прощще???
myTest();
txt1.text=a1;
txt2.text=a3;
};

function myTest(){

a3[0][i]=333;
i++;
if(i==9) i=0;
};

Эххх...а как элегантно выглядело бы a3=a1........

etc
15.10.2006, 23:32
var a1:Array = [[1,2,3,4,5,6,7,8,9],[1,2,3,4,5,6,7,8,9,10]];
getArrayCopy = function(arr:Array):Array {
var outArray:Array = new Array();
for (var i:Number=0;i<arr.length;i++) {
var item = arr[i];
if (Array(item)!=null&&item!=arr) {
outArray.push(getArrayCopy(item));
} else {
outArray.push(item);
}
}
return outArray;
}
a2 = getArrayCopy(a1);
a2[0][1] = 134;
trace([a1[0][1],a2[0][1]]); // 2,134
Сколки-угодно-мерный…

SiDDD
16.10.2006, 21:40
Пасиб большое за ответ! :rolleyes:

Но неужели нельзя прощще?? Этот код для примера был. На деле массив 100 на 100! Ролик 50 кадров в сек. В каждом кадре необходимо вносить изменения в копию массива не затрагивая оригинал.. Этож как всё будет тормозить то?! В C++, Basic, не грю уж про ASM - простенько и элегантно решается так... Хм.. Видно только не в Action Script?

Что по вашему коду - не прощще ли тогда так:
for(i=0;i<ВСЕГО_ЭТАЖЕЙ_МАССИВА;i++) a3[i]=a1[i].concat();

Эххх, абыдна да! Почему с одномерным массивом всё отлично работает а с многомерным уже указатели передаются..

Вот и хотелось бы услышать от знатоков - нельзя ли без циклов и прочих "излишеств" скопировать один "многоэтажный" массив в другой???

iNils
16.10.2006, 21:45
Не знаю как в Си, а в бейсике массиве были точно многомерные, а вот в АС многомерных массивом не существует. То что мы зовем многомерными массивами, являются лишь их эмуляцией, отсюда и проблемы.

etc
16.10.2006, 21:48
Нет, нельзя.

SiDDD
16.10.2006, 22:18
Драсти-приехали :mad: А как хорошо всё начиналось :D Тогда создам ещё одну тему... про String в роли массива. Можно да? :rolleyes:

BigDan
16.10.2006, 22:31
Массив в AS нельзя считать полноценным массивом, так как массив AS -это обьект с набором свойств(елементы "массива"). Возможно по этому так нельзя делать. Можно сделать так arr2=arr1, только в данном случае массив arr2 можно считать ссылкой на массив arr1, при изменении значения в массиве arr1 оно же будет менатся в массиве arr2, но можно менять елементы массива arr2 и эти изменения никак не повлияют на массив arr1.

SiDDD
16.10.2006, 22:45
Благодарю за ответы! Даж не ожидал такой отзывчивости :rolleyes: Признаюсь мануал читал а ангийским владею к сожалению не безупречно, потому и подумал - не упустил ли какой "секретной" функции. И сторонние книжечки перелистал не раз. Вот уперлось вощщем всё в эти массивы и точка... Пробую разные варианты - некоторые привел как пример. Ваши советы работают - но важна максимальная производительность.

SiDDD
16.10.2006, 23:18
Массив в AS нельзя считать полноценным массивом, так как массив AS -это обьект с набором свойств(елементы "массива"). Возможно по этому так нельзя делать. Можно сделать так arr2=arr1, только в данном случае массив arr2 можно считать ссылкой на массив arr1, при изменении значения в массиве arr1 оно же будет менатся в массиве arr2, но можно менять елементы массива arr2 и эти изменения никак не повлияют на массив arr1.

В том то и дело, что изменения в arr2 ещё как влияют на arr1. Ведь из ваших же слов - arr2 только ссылка на arr1 а не его копия.

Nirth
16.10.2006, 23:30
Можно копировать объекты с помощью класса mx.utils.ObjectCopy

посмотрите в классах поставляемых с флэшом документацию ( не в документации, а документацию в классе - комментарии)

iNils
16.10.2006, 23:37
Можно копировать объекты с помощью класса mx.utils.ObjectCopy

посмотрите в классах поставляемых с флэшом документацию ( не в документации, а документацию в классе - комментарии)
concat быстрее работает раз в 6, чем поэлементное копирование.