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

tooth212 22.07.2013 00:48

Количество элементов в массиве
 
Добрый день, как можно посчитать элементы массива?
Делал вот так:
Код AS3:

myarr.length

Но если элемент один, то выдается ошибка, как можно поправить код?

tsarapkabel 22.07.2013 01:11

Какая ещё ошибка? Никаких ошибок!
Код AS3:

var arr:Array = new Array();
trace(arr.length) //0;
 
arr.push(1);
trace(arr.length); //1


AlexCooper 22.07.2013 02:04

Не всегда
Код AS3:

arr.length

выдает правильно количество элементов в массиве. В частности когда происходят операции присвоении или удалении элементов массива через индекс ( то-есть не используя команды push, pop, shift и т.д.) Потому этот вариант думаю решит ваш вопрос
Код AS3:

 
function myLength(arr:Array):uint {
    var leng:uint = 0;
    for ( var i:String in arr ) leng++;
    return leng;
 
}
trace( myLength(myarr) );


iNils 22.07.2013 02:12

Цитата:

Сообщение от AlexCooper (Сообщение 1141622)
Не всегда
Код AS3:

arr.length

выдает правильно количество элементов в массиве. В частности когда происходят операции присвоении или удалении элементов массива через индекс ( то-есть не используя команды push, pop, shift и т.д.)

Да ладно? Сколько лет работаю с AS и не разу ни с чем подобным не сталкивался. Или вы про то, что в середине массива присвоили значение null, а length не изменился? Так и должно быть. Ведь элемент все равно существует и его значение null.

caseyryan 22.07.2013 07:55

Цитата:

Но если элемент один, то выдается ошибка
Интересно посмотреть, что за ошибка
готов поспорить, что она не связана с количеством элементов в массиве

Цитата:

Сообщение от AlexCooper (Сообщение 1141622)
Не всегда
Код AS3:

arr.length

выдает правильно количество элементов в массиве. В частности когда происходят операции присвоении или удалении элементов массива через индекс ( то-есть не используя команды push, pop, shift и т.д.) Потому этот вариант думаю решит ваш вопрос
Код AS3:

 
function myLength(arr:Array):uint {
    var leng:uint = 0;
    for ( var i:String in arr ) leng++;
    return leng;
 
}
trace( myLength(myarr) );


А как по вашему работает геттер get length?
Не так же?

AlexCooper 22.07.2013 11:41

Код AS3:

function myLength(arr:Array):uint {
    var leng:uint = 0;
    for ( var i:String in arr ) leng++;
    return leng;
 
}
 
var s:Array = new Array();
        s[1] = true;
        s[2] = true;
        s[5] = true;
 
trace(s.length); // 6
trace( myLength(s) ); // 3
 
s['t'] = true;
 
trace(s.length); // 6
trace( myLength(s) ); // 4


WisP 22.07.2013 11:54

http://help.adobe.com/en_US/FlashPla...t/3/Array.html
К вопросу о первом "trace(s.length); // 6":
Цитата:

Arrays are sparse arrays, meaning there might be an element at index 0 and another at index 5, but nothing in the index positions between those two elements. In such a case, the elements in positions 1 through 4 are undefined, which indicates the absence of an element, not necessarily the presence of an element with the value undefined.
Касательно "s['t'] = true;"
Цитата:

Do not use the Array class to create associative arrays (also called hashes), which are data structures that contain named elements instead of numbered elements. To create associative arrays, use the Object class. Although ActionScript permits you to create associative arrays using the Array class, you cannot use any of the Array class methods or properties with associative arrays.

AlexCooper 22.07.2013 12:19

WisP Спорить с Вами не стану, потому как это я и имел ввиду что если редактировать массив в ручном режиме ( не используя команды push, pop, shift и т.д. ( ну и естественно заполнение циклом или "индуским" методом )) то получиться то что получается у ТС. Других идей у меня нет почему у человека может выдавать "ошибку" arr.length кроме того что идет не правильный подход в использовании массива.

caseyryan 22.07.2013 13:07

Цитата:

Других идей у меня нет почему у человека может выдавать "ошибку" arr.length кроме того что идет не правильный подход в использовании массива.
А моя идея в том, что у него ошибка вообще с чем-то другим связана.

WisP 22.07.2013 13:11

О чем спорить-то))) Я просто указал на пару "стратегических" мест в коде и дал линк на статью, с которой не помешало бы ТС ознакомиться. Чтобы "мистические" ошибки не мешали работе.

AlexCooper 22.07.2013 13:36

Цитата:

Сообщение от caseyryan (Сообщение 1141650)
А моя идея в том, что у него ошибка вообще с чем-то другим связана.

Вполне возможно, но мне все же кажется проблема изначально в "ручном" заполнении массива. И наче какие могут быть проблемы при изменении размерности массива.

AlexLucas 22.07.2013 13:54

Текст ошибки в студию.

wvxvw 22.07.2013 15:03

Когда говорят про элементы массива, то имеют в виду именно то, что находится в array.length. Если у вас есть какие-то дополнительные требования, например, вам нужны только уникальные элементы, только те, которые не равны null / undefined и т.п. - это нужно уточнять, иначе вас не поймут.

AlexCooper 22.07.2013 15:32

Цитата:

Сообщение от wvxvw (Сообщение 1141671)
Когда говорят про элементы массива, то имеют в виду именно то, что находится в array.length. Если у вас есть какие-то дополнительные требования, например, вам нужны только уникальные элементы, только те, которые не равны null / undefined и т.п. - это нужно уточнять, иначе вас не поймут.

Хм... то-есть по Вашим словам этот массив не имеет элементов?
Код AS3:

var arr:Array = new Array();
arr['test'] = Math.random();
 
trace(arr.length); // 0


WisP 22.07.2013 16:03

А с чего вы взяли, что в arr.length именно 0.
Позволю себе повторить цитату: Although ActionScript permits you to create associative arrays using the Array class, you cannot use any of the Array class methods or properties with associative arrays.

AlexCooper 22.07.2013 16:16

Цитата:

Сообщение от WisP (Сообщение 1141680)
А с чего вы взяли, что в arr.length именно 0.

Это не я взял, так говорит компилятор.

AlexLucas 22.07.2013 16:26

@WisP, вы же сами это написали :)
Цитата:

Although ActionScript permits you to create associative arrays using the Array class, you cannot use any of the Array class methods or properties with associative arrays.
Геттер length учитывает только объекты с ключами типа uint.

WisP 22.07.2013 17:07

AlexLucas, ну так написано же: нельзя использовать методы или свойства класса Array с ассоциативными массивами.
В том числе, как только вопреки здравому смыслу возникло желание добавить строковый ключ, length использовать нельзя и обсуждение результата, который возвращает length уже не имеет смысла.

iNils 22.07.2013 17:48

Цитата:

Сообщение от AlexCooper (Сообщение 1141642)
Код AS3:

function myLength(arr:Array):uint {
    var leng:uint = 0;
    for ( var i:String in arr ) leng++;
    return leng;
 
}
 
var s:Array = new Array();
        s[1] = true;
        s[2] = true;
        s[5] = true;
 
trace(s.length); // 6
trace( myLength(s) ); // 3
 
s['t'] = true;
 
trace(s.length); // 6
trace( myLength(s) ); // 4


О чем я и говорил. Ни какой ошибки нет, элементов в массиве 6 штук и занимают позиции: 0,1,2,3,4,5.

AlexLucas 22.07.2013 17:49

Не нельзя, а не рекомендуется, раз ошибку не выдаёт - значит можно. И результат в том случае всегда будет 0.

AlexCooper 22.07.2013 18:15

iNils прошу прощения. А где элемент с индексом 't'?
Код AS3:

var s:Array = new Array();
        s[1] = true;
        s[2] = true;
        s[5] = true;
 
        s['t'] = true;
 
 
for ( var i=0; i<s.length; i++ ){
        trace(i+" > "+s[i]);
}
 
/*
0 > undefined
1 > true
2 > true
3 > undefined
4 > undefined
5 > true
*/


WisP 22.07.2013 20:11

Цитата:

Сообщение от AlexLucas (Сообщение 1141704)
Не нельзя, а не рекомендуется, раз ошибку не выдаёт - значит можно. И результат в том случае всегда будет 0.

Могу только предложить обратиться к словарю.

iNils 22.07.2013 21:04

Цитата:

Сообщение от AlexCooper (Сообщение 1141711)
iNils прошу прощения. А где элемент с индексом 't'?

А он разве там должен быть? Вы справку читали? Если вы возьмете молоток, и начнется вместо гвоздя бить по пальцу, то тоже скажите, что молоток не работает? У Array есть четкая логика работы с элементами массива. Индекс элемента - число. Длина массива, это не количество добавленных туда элементов, это число элементов между последним и первым индексами. Потому что массив непрерывен. И даже, если вы туда что-то не поместили, ячейка резервируется.

У MovieClip нет свойства length, но можно написать так
Код AS3:

var m:Array = new MovieClip();
m['t'] = true;

Ничего не напоминает? Может MovieClip тоже не правильно работает?

AlexCooper 22.07.2013 22:38

iNils Согласен с Вами и признаю что считал запись вида
Код AS3:

var m:Array = new Array();
m['t'] = true;

как запись в массив значения с индексом t. Но в свою очередь не использую такой подход, может на ранних этапах программирования, потому и предположил что подобную ошибку мог допустить ТС.

wvxvw 23.07.2013 01:30

Цитата:

Сообщение от AlexCooper (Сообщение 1141677)
Хм... то-есть по Вашим словам этот массив не имеет элементов?
Код AS3:

var arr:Array = new Array();
arr['test'] = Math.random();
 
trace(arr.length); // 0


Когда говорят о массиве, то подразумевают определенную структуру данных. Такая структура характеризуется тем, что помимо всего прочего в ней все элементы упорядочены (линейно упорядоченое множество) когда вы записываете в массив что-то по индексу "вася", то вы должны определится с вопросом: находится ли индекс "вася" раньше индекся N, или нет. Т.как вы этого не можете сделать (либо "вася" будет равен какому-нибудь числу N, либо ваш массив перестанет быть линейно упорядоченным).
Поведение которое вы видите не типично для массивов вообще, и является случайным артефактом, продуктом наследования + специфики реализации динамического доступа. Лучше об этом думать как о методе `[]` определенном на классе Array таким образом, что будучи вызваным со строкой в качестве индекса не вернет элемент по индексу, а значение динамически созданного свойства.

alexcon314 23.07.2013 08:41

Вспомнился давний холивар на тему "массивы в AS индексируются строками". Что-то тогда много всякого наговорили.. правда, AS 3.0 тогда еще не было вроде даже.

Код AS3:

var arr:Array = new Array();
arr['0'] = 123456;
trace(arr.length); // 1
trace(arr[0]); //123456

UPD. Пардон, вот оно, тем более поностальгировать: ActionScript - полная лажа" или "Как не надо делать интерпретаторы"

FlashRus 23.07.2013 09:05

Цитата:

А как по вашему работает геттер get length?
Он не пересчитывает элементы каждый раз.

Код:

uint32 ArrayObject::get_length() const {
        return getLength();
}

/*virtual*/ uint32 ArrayObject::getLength() const {
        return m_length;
}

Добавлено через 1 час 58 минут
Код:

uint32 ArrayObject::AS3_push(Atom* argv, int argc) {
        if (isSimpleDense()) {
                m_denseArr.push (argv, argc);
                m_length += argc;
        } else {
                for (int i=0; i < argc; i++) {
                        _setUintProperty(getLength(), argv[i]);
                }
        }
        return m_length;
}

"m_length += argc;" - новая длина массива собственной персоны


Добавлено через 2 часа 58 минут
Результаты тестов:

0 => 987, 987, 0
1000 => 987, 987, 0
10000000 => 1929, 1929, 0


Код AS3:

addEventListener(MouseEvent.CLICK, clickHandler)
var arr:Array = [];
var currLength:int;
var t0:int;
var t1:int;
var i:int;
 
function clickHandler(e:MouseEvent):void {
        calculateAndAppendData()       
        for (i = 0; i < 1000; i++) {
                arr.push(Math.random())
        }
        calculateAndAppendData();
        arr = [];
        for (i = 0; i < 10000000; i++) {
                arr.push(Math.random())
        }
        calculateAndAppendData();
}
 
function calculateAndAppendData():void {
        t0 = getTimer();
        currLength = arr.length;
        t1 = getTimer();
        tf.appendText(currLength + " => " + t0 + ", " + t1 + ", " + (t1 - t0) + "\n");
}



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

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