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

PNATd 21.01.2012 18:34

Изменение элемента двумерного массива
 
Создаю в Action Script двумерный массив Arr, заполняю его числовыми данными. Затем мне требуется менять эти данные. Пробую сделать это командой Arr[1][1] = 5, в результате все значения второго столбца, а не только второй ячейки меняются на 5. Что я делаю неправильно, и как менять значения в двумерном массиве?

Zebestov 21.01.2012 19:26

Покажи, как создаешь и заполняешь двумерный массив.

PNATd 21.01.2012 21:27

Я создала специальную программу для проверки, чтобы избежать влияния посторонних ошибок. Происходит то же самое.
Создание и заполнение массива следующее:
Код AS3:

var Arr:Array = new Array();
var Arr2:Array = new Array();
for (var i:Number=0; i<5; i++)
{
        for (var j:Number=0; j<5; j++)
        {
                Arr[j] = 5;
        }
        Arr2[i] = Arr;
}

Trace выводит массив, заполненный числами 5. После команды
Код AS3:

Arr2[0][0] = 1;

массив принимает следующий вид:
1,5,5,5,5
1,5,5,5,5
1,5,5,5,5
1,5,5,5,5
1,5,5,5,5

iNils 21.01.2012 21:43

Массив, это объект. А все объекты передают на себя ссылки, а не значения.
Поэтому, все элементы массива Arr2, хранят в себе ссылки на массив Arr.
Поэтому, нужно делать так:
Код AS3:

var arr:Array = [];
for (var i:Number = 0; i < 5; i++) {
        arr[i] = [];
        for (var j:Number=0; j<5; j++) {
                arr[i][j] = 5;
        }
}
arr[0][0] = 1;

PS. В ActionScript принято писать названия переменных с маленькой буквы.

PNATd 21.01.2012 21:59

Все заработало. Спасибо за помощь!

wvxvw 21.01.2012 22:12

Если максимальный размер двухмерного массива не критичен, то я бы имитировал двумерные массивы через один одномерный, но с доступом и чтением по формуле i * w + j, где i - смещение по вертикали, w - количество колонок, j - смещение по горизонтали. Таким образом можно избежать создания лишних вложенных массивов.

GBee 21.01.2012 22:20

wvxvw, а есть еще плюсы вашего подхода, кроме избегания создания лишних массивов?

iNils 21.01.2012 22:20

Цитата:

Сообщение от wvxvw (Сообщение 1058340)
Если максимальный размер двухмерного массива не критичен, то я бы имитировал двумерные массивы через один одномерный, но с доступом и чтением по формуле i * w + j, где i - смещение по вертикали, w - количество колонок, j - смещение по горизонтали. Таким образом можно избежать создания лишних вложенных массивов.

При возрастании массива, это приведет к проблемам.

silin 21.01.2012 23:17

>>При возрастании массива, это приведет к проблемам.
а кто-нибудь мерял-тестил на каких длинах начинаются проблемы ?
и да: а каких проблем тут ждать

Zebestov 21.01.2012 23:29

:D речь, наверное, шла об увеличении количества столбцов

silin 21.01.2012 23:36

да как бы поровну столбцов или строк, если речь в конечном итоге об одномерном массиве, проблемы, надо понимать, должны быть у него, не?

Zebestov 21.01.2012 23:52

Проблемы будут при динамическом изменении количества столбцов в "одномерной" реализации. Но точно ли их имел в виду iNils, я не берусь утверждать.

silin 21.01.2012 23:57

упс, ну да, понятно
я чего не туда подумал

fish_r 22.01.2012 01:34

4 294 967 295 последняя длинна с которой удалось создать массив, с бОльшей длинной он не создается )

wvxvw 22.01.2012 04:26

Ну, пришлось бы определить дополнительные функции для удаления / добавления столбцов (как будто в эмуляции вложенными массивами они есть - там просто тривиально их прикрутить, а с одним массивом - менее тривиально, но не нейтронная сеть, все-таки :))

А какие будут проблемы при возрастании? Я вижу только проблему в том, что вложенные массивы могут вместить int.MAX_VALUE * int.MAX_VALUE (это в далеком будущем, когда у любого ПК будет столько же памяти как у современных суперкомпьютеров :)), а у одномерного массива будет всего int.MAX_VALUE.

fish_r 22.01.2012 07:48

Цитата:

вложенные массивы могут вместить int.MAX_VALUE * int.MAX_VALUE
(int.MAX_VALUE * 2) * ( int.MAX_VALUE * 2 ) (то то мне число 4 294 967 295 подозрительным показалось :) )

и это только двухмерные, если предположить, что вложенность может равняться примерно тому же imt.MAX_VALUE * 2 получается: теоретически макс. кол-во эл-тов может равняться imt.MAX_VALUE * 2 в степени imt.MAX_VALUE * 2 (Number-a то хватит чтобы отразить это число?). :quiet:

GBee 22.01.2012 11:47

Цитата:

то то мне число 4 294 967 295 подозрительным показалось
Диапазон значений представленных классом uint составляет от 0 до 4294967295 (2 в степени 32 - 1).
И length массива uint, кстати.

iNils 22.01.2012 15:09

Цитата:

Сообщение от Zebestov (Сообщение 1058346)
:D речь, наверное, шла об увеличении количества столбцов

Именно об этом.

LOS2008 22.01.2012 18:33

Типизированные данные хранить надо в Vector.

wvxvw 23.01.2012 02:06

Код AS3:

package tld.doodles.collections
{
        public class Array2D
        {
                public static const COLUMN:Array2D = new Array2D();
 
                public static const ROW:Array2D = new Array2D();
 
                public function get length():uint { return this._items.length; }
 
                public function get columns():uint { return this._columns; }
 
                public function get rows():uint
                {
                        return this._items.length / this._columns;
                }
 
                protected const _items:Array = [];
 
                protected var _columns:uint;
 
                public function Array2D() { super(); }
 
                public static function make(columns:uint,
                        rows:uint = 0, array:Array = null):Array2D
                {
                        var result:Array2D = new Array2D();
 
                        if (!array) array = [];
                        result._columns = columns;
                        array.length = Math.max(array.length, columns * rows);
                        result._items.push.apply(result, array);
                        return result;
                }
 
                public static function get(array:Array2D, x:uint, y:uint):Object
                {
                        return array._items[x * array._columns + y];
                }
 
                public static function set(array:Array2D, x:uint, y:uint,
                        value:Object):Object
                {
                        return array._items[x * array._columns + y] = value;
                }
 
                public static function insertColumns(array:Array2D,
                        position:uint, howMany:uint, feeder:Function):Array2D
                {
                        var times:uint = array.rows;
                        for (var i:int; i < times; i++)
                                array._items.splice.apply(
                                        array._items,
                                        [position + howMany * i + array._columns * i, 0].concat(
                                                new Array(howMany).map(feeder)));
                        array._columns += howMany;
                        return array;
                }
 
                public static function insertRows(array:Array2D,
                        position:uint, howMany:uint, feeder:Function):Array2D
                {
                        array._items.splice.apply(
                                array._items, [position * array._columns, 0].concat(
                                        new Array(howMany * array._columns).map(feeder)));
                        return array;
                }
 
                public static function forEach(array:Array2D, kind:Array2D,
                        callback:Function):Array2D
                {
                        var element:Array;
                        var iterations:uint;
 
                        if (kind == COLUMN)
                        {
                                iterations = array._columns;
                                for (var i:int; i < iterations; i++)
                                {
                                        callback(fetchColumn(
                                                i, array._columns, array._items, element), i);
                                        setColumn(array, i, element);
                                }
                        }
                        return array;
                }
 
                public static function setColumn(array:Array2D, column:uint,
                        elements:Array):Array2D
                {
                        var arrayLength:uint = array.length;
 
                        for (var i:int; column < arrayLength; column += array._columns, i++)
                                array._items[column] = elements[i];
                        return array;
                }
 
                public static function setRow(array:Array2D, row:uint,
                        elements:Array):Array2D
                {
                        elements.length = array._columns;
                        array._items.splice.apply(
                                array._items, [row * array._columns, elements.length]
                                        .concat(elements));
                        return array;
                }
 
                private static function fetchColumn(offset:uint, step:uint,
                        source:Array, destination:Array):Array
                {
                        destination.length = 0;
                        var sourceLength:uint = source.length;
                        for (; offset < sourceLength; offset += step)
                                destination.push(source[offset]);
                        return destination;
                }
 
                private static function fetchRow(row:uint, rowLength:uint,
                        destination:Array, source:Array):Array
                {
                        var start:uint = row * rowLength;
                        var end:uint = start + rowLength;
 
                        destination.length = 0;
                        for (var j:int, i:int = start; i < end; i++, j++)
                                destination[j] = source[i]
                        return destination;
                }
 
                public static function print(array:Array2D):String
                {
                        var filler:String;
                        var top:String;
                        var bottom:String;
                        var rows:Array = [];
                        var totalRows:uint = array.rows;
                        var row:Array = [];
                        var maxLength:uint;
                        var rowString:String;
                        var column:Array = [];
                        var mask:Array = [];
                        var columnsDestination:Array = new Array(array.rows + 1).join("&#9474;").split("");
                        var j:uint;
 
                        for (var i:uint; i < array._columns; i++)
                        {
                                column = fetchColumn(i, array._columns, array._items, column);
                                maxLength = 0;
                                for (j = 0; j < totalRows; j++)
                                {
                                        if (i == array._columns - 1)
                                                column[j] = rowString = " " + String(column[j]);
                                        else column[j] = rowString = " " + String(column[j]) + ",";
                                        maxLength = Math.max(maxLength, rowString.length);
                                }
                                for (j = 0; j < totalRows; j++)
                                {
                                        rowString = column[j];
                                        mask.length = (maxLength - rowString.length) + 1;
                                        columnsDestination[j] += rowString + mask.join(" ");
                                        if (i == array._columns - 1)
                                                columnsDestination[j] += " &#9474;\n";
                                }
                        }
                        filler = new Array(String(columnsDestination[0]).length - 2).join("&#9472;");
                        top = "&#9484;" + filler + "&#9488;\n";
                        bottom = "&#9492;" + filler + "&#9496;";
                        return top + columnsDestination.join("") + bottom;
                }
        }
}

Дело было вечером, делать было... на самом деле было чего :)
Код AS3:

private function testArray2D():void
{
        var array:Array2D = Array2D.make(4, 5);
        trace(Array2D.print(array));
        Array2D.setColumn(array, 2, [1, 2, 3]);
        trace(Array2D.print(array));
        Array2D.setRow(array, 2, [5, 6, 7]);
        trace(Array2D.print(array));
        Array2D.insertColumns(array, 3, 4, Math.max);
        trace(Array2D.print(array));
}

Код:

┌────────────────────────────────────────────┐
│ undefined, undefined, undefined, undefined │
│ undefined, undefined, undefined, undefined │
│ undefined, undefined, undefined, undefined │
│ undefined, undefined, undefined, undefined │
│ undefined, undefined, undefined, undefined │
└────────────────────────────────────────────┘
┌────────────────────────────────────────────┐
│ undefined, undefined, 1,        undefined │
│ undefined, undefined, 2,        undefined │
│ undefined, undefined, 3,        undefined │
│ undefined, undefined, undefined, undefined │
│ undefined, undefined, undefined, undefined │
└────────────────────────────────────────────┘
┌────────────────────────────────────────────┐
│ undefined, undefined, 1,        undefined │
│ undefined, undefined, 2,        undefined │
│ 5,        6,        7,        undefined │
│ undefined, undefined, undefined, undefined │
│ undefined, undefined, undefined, undefined │
└────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────┐
│ undefined, undefined, 1,        NaN, NaN, NaN, NaN, undefined │
│ undefined, undefined, 2,        NaN, NaN, NaN, NaN, undefined │
│ 5,        6,        7,        NaN, NaN, NaN, NaN, undefined │
│ undefined, undefined, undefined, NaN, NaN, NaN, NaN, undefined │
│ undefined, undefined, undefined, NaN, NaN, NaN, NaN, undefined │
└────────────────────────────────────────────────────────────────┘


iNils 23.01.2012 02:13

И ради чего такой огород?

wvxvw 23.01.2012 03:48

Например, для настольных игр, где имеет место быть доска типа шахматной. Очень часто нужно работать с ней (доской) как с сетом, и одновременно иметь возможность задавать значения через x/y. Могут быть варианты, где для прсчета, или просто для запоминания действий, может понадобиться хранить состояние доски - хранить кучу лишних массивов в такой ситуации может быть накладно...


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

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