Беларусь, рогачёв |
Контейнеры
Создание массива с помощью квадратных скобок
Однако необязательно создавать массивы именно с помощью оператора new. Есть и другой способ, который вы, возможно, сочтете более удобным. Оказывается, перечисление элементов массива в квадратных скобках через запятую полностью эквивалентно его созданию при помощи new с использованием первого конструктора (в котором также перечисляются элементы массива ). Вот пример:
i = 1 a_array = [2, i, 0, 5, null]; i = 3; // Обращаемся по номеру, записанному в переменной trace("a[" + i + "] = " + a_array[i]); // Выводим весь массив целиком trace(a_array);
На выходе мы получим:
a[3] = 5 2,1,0,5,null
Все как и следовало ожидать. Заметьте, что функция trace легко смогла вывести весь массив целиком - на самом деле эта функция справится и с любым другим объектом, у которого определен метод toString(). То есть записи trace(a_array) и trace(a_array.toString()) эквивалентны.
А что будет, если записать нечто в индекс, который находится за пределами массива? Оказывается, все произойдет наилучшим образом: массив расширится как раз до тех пор, чтобы вместить новое поле. Впрочем, индекс должен быть целым и неотрицательным. При попытке что-либо прочесть из нецелого или отрицательного индекса мы получим undefined. Попытка записи в нецелый индекс за границей массива дает смешной результат: массив расширяется, но просто так, при обычном переборе нецелый индекс не виден. К нему можно обратиться лишь напрямую. Вот примеры всего этого: запускаем следующий код
a = [12, 22]; a[5] = 77; trace("a = " + a); b = [33, 44, 55]; b[-1] = 88; trace("b = " + b); trace("b[1.7] = " + b[1.7]); trace("b[Math.ceil(1.7)] = " + b[Math.ceil(1.7)]); trace("b[8] = " + b[8]); a[9.81] = 333; trace("a = " + a); trace("a[9.81] = " + a[9.81]);
и получаем:
a = 12,22,,,,77 b = 33,44,55 b[1.7] = b[Math.ceil(1.7)] = 55 b[8] = a = 12,22,,,,77,,,, a[9.81] = 333
Если вас заинтересовало поведение массива для нецелых ключей, вы можете просмотреть чуть дальше параграф о нечисловых ключах. Вы сразу поймете причины такого поведения.
Многомерные массивы, создание массива "на лету"
А вот как делаются во Флэш МХ многомерные массивы:
i = 7; a_array = [[i, i+1], [i+2, i+3], [1, 2], [3, 4, 5, 6], "aaaaaaa"]; // Обращаемся к конкретному элементу trace("a_array[1][1] = " + a_array[1][1]); // Выводим подмассив trace("a_array[3] = " + a_array[3]); // Выводим список всех элементов субмассивов trace("a_array = " + a_array); // Создание массива "на лету" trace([100, 23, -3]);
Приведенный здесь код выводит:
a_array[1][1] = 10 a_array[3] = 3,4,5,6 a_array = 7,8,9,10,1,2,3,4,5,6,aaaaaaa 100,23,-3
Из этого примера можно заключить, что многомерный массив во Флэше не является специальным случаем массива (как и в C/C++). Более того, вовсе не каждый элемент многомерного массива в свою очередь должен являться массивом. Просто каждый элемент массива может быть объектом любого типа - примитивного или нет. В том числе - другим массивом.
Однако с этой точки зрения строчка
a_array = [[i, i+1], [i+2, i+3], [1, 2], [3, 4, 5, 6], "aaaaaaa"];
выглядит так, как будто субмассивы были созданы прямо по ходу дела - вместо записи вида
temp1_array = [i, i+1]; temp2_array = [i+2, i+3]; temp3_array = [1,2]; temp4_array = [3, 4, 5, 6]; a_array = [temp1_array, temp2_array, temp3_array, temp4_array, "aaaaaaa"];
То есть возникает впечатление, что создать массив можно прямо "на лету", внутри любой части какого-нибудь выражения. Это подтверждает последняя строчка вышеприведенного примера: trace([100, 23, -3]); действительно выводит содержание созданного прямо внутри функции trace массива. Более того, следующий код, на первый взгляд кажущийся безумным, также компилируется и работает:
trace(([1, 2, 3])[2]) trace([1, 2, 3][0]) trace([10][0]) trace([3,7, 2, -1].sort())
Выводит он
3 1 10 -1,2,3,7
В первой строчке мы на всякий случай взяли в круглые скобки создание массива. Вторая строчка подтверждает, что и без круглых скобок Флэш может отличить, где скобки квадратные означают создание массива, а где - обращение к его ячейке по номеру. Третья строчка подтверждает, что это различие состоит вовсе не в количестве чисел в скобках, а в том, стоит ли слева от квадратных скобок подвыражение, представляющее собой массив, или же нет (в последнем случае массив создается). Наконец, четвертая строка - демонстрация того, что с только что созданным массивом можно производить такие же операции (например, вызов методов), как и с массивом, созданным заранее.
Напоследок - нечто, более напоминающее загадку, чем имеющее какой-либо практический смысл. Что выводит следующая строка: trace([1, 2, 3, 4, 5][2, 0, 7, 3]);? Если ответ не сразу приходит вам в голову, то попробуйте разгадать, почему в результате выполнения этой строчки печатается 4? Разгадка же состоит в том, что Флэш лишь первые квадратные скобки воспринимает как указание создать массив. Вторые (увидев, что массив слева от них уже стоит) он воспринимает как обращение к ячейке массива. А выражение внутри них - как определяющее индекс этой ячейки. Вычислив это выражение (по правилам пользования операцией "запятая"), он получает, что оно равно самому правому числу в последовательности, то есть 3. А элемент массива, к которому мы обращаемся, имеющий индекс 3, - это и есть четверка.