PDA

Просмотр полной версии : Многомерные массивы в AS 3.0


van2tus
29.10.2010, 21:50
Здравствуйте, я совсем недавно начал изучать Action Script 3.0 и у меня появился такой вопрос как создать двумерный массив?

В руководстве от Adobe был такой пример:

var masterTaskList:Array = new Array();
masterTaskList[0] = ["wash dishes", "take out trash"];
masterTaskList[1] = ["wash dishes", "pay bills"];
masterTaskList[2] = ["wash dishes", "dentist", "wash dog"];
masterTaskList[3] = ["wash dishes"];
masterTaskList[4] = ["wash dishes", "clean house"];
masterTaskList[5] = ["wash dishes", "wash car", "pay rent"];
masterTaskList[6] = ["mow lawn", "fix chair"];

Он описывает случай, когда заранее известно количество элементов массива, и их не так много что бы прописать каждый элемент руками. А как сделать например массив, размерность, которого может быть до 1000х1000, и при этом я не знаю сколько элементов мне потребуется в отдельном случае.

Заранее спасибо за ответ.

P.S. Извиняюсь, если дублирую тему... искал не нашел...

КорДум
29.10.2010, 21:54
var i:uint;
var j:uint;
var arr:Array = [];
for (i = 0; i < 1000; i++) {
arr[i] = [];
for (j = 0; j < 1000; j++) {
arr[i][j] = String(i) + "_" + String(j);
}
}

van2tus
29.10.2010, 21:59
Спасибо )

goldlider
15.11.2010, 21:17
Дан такой код:


const M_HEIGHT = 15; // Строка
const M_WIDTH = 20; // Столбец

function ABC():void
{
massiv:Array = [];
massiv.length = M_HEIGHT;

for (var ay:int = 0; ay < M_HEIGHT, ay++)
{
massiv = [];
massiv[ay].length = M_WIDTH;

for (var ax:int = 0; ax < M_WIDTH, ax++)
{
massiv[ay][ax] = CELL_FREE // Какое-нибудь значение
}
}
}



Теперь вопросы:

1. Почему при инициализации нужно присвоить хотя бы какое-то значение ? В данном примере massiv:Array = []; Нельзя ли написать просто massiv:Array. Ведь в данном коде далее идет присвоение массиву значения massiv[ay][ax] = CELL_FREE.

2. Почему при задании длины массиву обращаться приходиться так massiv.length = M_HEIGHT;, а не так massiv[ay].length = M_HEIGHT;,

а вместо massiv[ay].length = M_WIDTH; вот так massiv[ax].length = M_WIDTH;

КорДум
15.11.2010, 22:35
1. Почему при инициализации нужно присвоить хотя бы какое-то значение ?
Потому что massiv:Array лишь типизирует переменную, но никак не говорит ей, что она новый массив.
2. Почему при задании длины массиву обращаться приходиться так massiv.length = M_HEIGHT;, а не так massiv[ay].length = M_HEIGHT;
В смысле? massiv - Это внешний массив, а massiv[ay] - внутренний, что непонятного?
Кроме того, massiv[ay] - это элемент массива massiv, а massiv[ay][ax] - элемент массива massiv[ay].

udaaff
15.11.2010, 22:43
goldlider, где вы этот код выкопали?

const M_HEIGHT = 15; // Строка
const M_WIDTH = 20; // Столбец

function ABC():void
{
var massiv:Array = [];
massiv.length = M_HEIGHT;

for (var ay:int = 0; ay < M_HEIGHT; ay++)
{
massiv = [];
massiv[ay].length = M_WIDTH;
massiv[ay] = [];

for (var ax:int = 0; ax < M_WIDTH; ax++)
{
massiv[ay][ax] = CELL_FREE // Какое-нибудь значение
}
}
}

goldlider
15.11.2010, 22:55
КорДум, Поправь меня если я не прав. Т.е. получается, что для задания длины одномерного массива мы используем запись massiv.length = 50; не используя никакие квадратные скобки.
А при вызове массива в цикле используется запись massiv[i]
Для двумерного массива мы используем запись massiv[j].length = 50; При вызове массива в цикле используется запись massiv[i,j]
Для трехмерного массива massiv[j,k] = 50; При вызове массива в цикле используется запись massiv[i,j,k]
Т.е. в квадратных скобках при задании длины пишется на одну переменную меньше.

Добавлено через 4 минуты
goldlider, где вы этот код выкопали?

const M_HEIGHT = 15; // Строка
const M_WIDTH = 20; // Столбец

function ABC():void
{
var massiv:Array = [];
massiv.length = M_HEIGHT;

for (var ay:int = 0; ay < M_HEIGHT; ay++)
{
massiv = [];
massiv[ay].length = M_WIDTH;
massiv[ay] = [];

for (var ax:int = 0; ax < M_WIDTH; ax++)
{
massiv[ay][ax] = CELL_FREE // Какое-нибудь значение
}
}
}

не важно. В нем все верно. Просто вопрос возник насчет массива. Это всего лишь часть кода.

КорДум
15.11.2010, 23:03
Да, так.
При вызове massiv[i,j,k]
Только пишите правильно - massiv[j][k]
Т.е. в квадратных скобках при указании длины пишется на одну переменную меньше.
Нужно [I]понимать, что такое массив и элемент массива, являющийся массивом.

goldlider
15.11.2010, 23:09
Да, так.

Только пишите правильно - massiv[j][k]

Нужно [I]понимать, что такое массив и элемент массива, являющийся массивом.

Объясните на пальцах, что такое элемент массива, являющийся массивом ? Или же в какой книге это можно найти. В книге Мука подобное не нашел.

КорДум
15.11.2010, 23:16
В ас3 нет многомерных массивов. Их можно сымитировать. В книге Мука как раз это и есть. 244 страница даже.
[ [], [], [], ..., [] ] - вот так имитируется двумерный массив. Его элементы - тоже массивы. Понятно теперь стало?

-De-
15.11.2010, 23:18
var massiv:Array;//это просто указатель
trace(massiv);//он никуда не указывает, память не выделена
massiv = [];//теперь это действительно массив, указатель указывает на новый "настоящий" массив
trace(massiv);

Как-то так. Вообще я бы рекомендовал не городить такую сложную структуру как массив массивов для двумерного, если его ширина или высота заранее известна и не меняется, а сделать одномерный.
Т.е. вместо massiv[i][j] писать massiv[i + j*M_HEIGHT] и всех делов.

Psycho Tiger
15.11.2010, 23:30
В ас3 нет многомерных массивов. Их можно сымитировать. В книге Мука как раз это и есть. 244 страница даже.
[ [], [], [], ..., [] ] - вот так имитируется двумерный массив. Его элементы - тоже массивы. Понятно теперь стало?
Хм, я всегда считал что двумерный массив - это массив масивов. А как правильно?
не важно. В нем все верно.
Когда в таком коде всё верно помогать Вам бессмысленно. У вас какой-то другой язык.

gloomyBrain
15.11.2010, 23:39
А как правильно?

Правильно считать иначе =) (Ваш К.О.)

@goldlider

не важно. В нем все верно.

В любом коде все верно. Правда, не любой делает то, что Вы хотите (как, на пример, в Вашем случае)

КорДум
15.11.2010, 23:41
Psycho Tiger, я всегда считал, что это таблица, без вложенностей.

medvedya2
15.11.2010, 23:48
n мерный массив это последовательность элементов, где к каждый элементу осуществляется доступ через n-мерный индекс [][][].., в памяти массив всегда одномерный.
в as3 к сожалению не так.

f.g.programmer
16.11.2010, 00:02
n мерный массив это последовательность элементов, где к каждый элементу осуществляется доступ через n-мерный индекс [][][].., в памяти массив всегда одномерный.
в as3 к сожалению не так.
Это в том случае, если массив типизирован и имеет фиксированную размерность. Никаких сожалений, а as3 просто универсальная реализация.

-De-
16.11.2010, 00:07
Одно измерение может не иметь фиксированный размер (см. выше как оно переиндексируется). Ну и в случае, когда хранятся указатели, можно договориться с типизацией.

goldlider
16.11.2010, 00:08
var massiv:Array;//это просто указатель
trace(massiv);//он никуда не указывает, память не выделена
massiv = [];//теперь это действительно массив, указатель указывает на новый "настоящий" массив
trace(massiv);

Как-то так. Вообще я бы рекомендовал не городить такую сложную структуру как массив массивов для двумерного, если его ширина или высота заранее известна и не меняется, а сделать одномерный.
Т.е. вместо massiv[i][j] писать massiv[i + j*M_HEIGHT] и всех делов.

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

-De-
16.11.2010, 00:21
"[]" - то же самое, что и "new Array()". _Заново_ выделять не надо. Но выделять надо.
Если мы хотим использовать массив, то мы его должны создать (выделить память). Если этот массив - элемент другого массива, то всё равно должны.

goldlider
16.11.2010, 00:32
De, что за белиберда получается. Как понять ваши слова "Заново выделять не надо. Но выделять надо."
В данном примере

var i:uint;
var j:uint;
var arr:Array = []; // Здесь память выделяется один раз
for (i = 0; i < 1000; i++) {
arr[i] = []; // Память выделяется при очередном увеличении i
for (j = 0; j < 1000; j++) {
arr[i][j] = String(i) + "_" + String(j);
}
}

Psycho Tiger
16.11.2010, 00:33
Верно.

-De-
16.11.2010, 11:28
В смысле, что два и больше раз под одно и то же выделять не надо, конечно.
var i:uint;
var j:uint;
var arr:*;//arr - не массив пока, нулевой указатель, не можем обращаться arr[i]
arr = []; // теперь массив и можем
for (i = 0; i < 1000; i++) {
//arr[i] - не массив, он то же самое, что был arr, нулевой указатель пока, не можем обращаться arr[i][j]
arr[i] = []; // теперь arr[i] массив, можно обращаться к arr[i][j]
for (j = 0; j < 1000; j++) {
arr[i][j] = String(i) + "_" + String(j);
}
}

cleptoman
16.11.2010, 12:01
а , кстате вопрос - массив с заданной заранее длиной элементов работает шустрее или по барабану?

gloomyBrain
16.11.2010, 13:11
На сколько я помню - для Array это безразлично. Для Vector есть разница, если он fixed

deamoK
16.11.2010, 13:16
именно массив - абсолютно по-барабану, проверил ща несколько раз: 10к спрайтов создаются в массиве за 47-78мс без задания размера, с заранее заданным размером скорость прыгает так же 47-78мс

goldlider
16.11.2010, 13:43
De, так вы говорите, что память для внутреннего массива в цикле выделяется один раз. Так ? Я просто понять вас немогу одни говорят одно, а другие совсем другое.

-De-
16.11.2010, 14:09
ну да, для каждого из внутренних массивов память выделяется только раз в этом примере, пример вполне годен и применим.