AS3: как преобразовать вектор в массив - PullRequest
23 голосов
/ 10 июля 2009

Какой самый лучший способ преобразовать вектор в массив в Actionscript3?

Нормальный синтаксис приведения не работает:

var myVector:Vector.<Foo> = new Vector();
var myArray:Array = Array(myVector); // calls the top-level function Array()

из-за наличия функции Array. Выше приведен массив, но это массив с единственным элементом, состоящим из исходного вектора.

Что оставляет немного более многословным:

var myArray:Array = new Array();
for each (var elem:Foo in myVector) {
    myArray.push(elem);
}

это нормально, я думаю, хотя и немного многословно. Это канонический способ сделать это, или есть функция toArray (), скрывающаяся где-то в стандартной библиотеке?

Ответы [ 8 ]

24 голосов
/ 10 июля 2009

ваш подход самый быстрый ... если вы думаете, что это многословно, то создайте служебную функцию ...:)

редактирование:

Чтобы построить служебную функцию, вам, вероятно, придется отбросить тип следующим образом:

function toArray(iterable:*):Array {
     var ret:Array = [];
     for each (var elem:Foo in iterable) ret.push(elem);
     return ret;
}
18 голосов
/ 10 июля 2009

Существует функция forEach, которую вы можете использовать как в Vector, так и в Array. В основном это вызывает функцию для каждого элемента в векторе. Вот как это работает:

var myVector:Vector.<Foo> = new Vector();
var myArray:Array = [];

myVector.forEach(arrayConverter);

function arrayConverter(element:*, index:int, array:Array):void{
    myArray[myArray.length] = element;
}

Но я не смог найти функцию, которая просто перемещает все значения из вектора в массив. Другое решение может состоять в том, что вы создаете класс, который расширяет класс Vector, а затем у вас есть открытая функция toArray (), и затем у вас есть этот код в этой функции, поэтому вам не нужно писать его каждый раз, когда вы хотите преобразовать.

Векторная документация

Редактировать: Нашел этот старый вопрос сегодня и подумал, что было бы интересно провести тестовый тест всех различных методов в это воскресное утро.

Я использовал вектор с 1000000 элементами и сделал 2 теста для каждой петли. Один использует встроенные функции массива push, а другой - обычные операции с массивами.

  • Для цикла, не нажимайте: 520 мс
  • Для цикла нажмите: 1027 мс
  • цикл по каждому элементу, а не push: 1753 мс
  • цикл по каждому элементу, нажмите: 2264 мс
  • Во время цикла, не нажимайте: 2775 мс
  • Во время цикла, не нажимайте: 3282 мс
  • Использовать цикл, не нажимать: 4059 мс
  • Util loop, нажмите: 4570 мс

А вот эталонный тест с использованием 1000 единиц:

  • Для цикла, не нажимайте: 1 мс
  • Для цикла нажмите: 2 мс
  • цикл по каждому элементу, а не push: 2 мс
  • цикл по каждому элементу, нажмите: 3 мс
  • Во время цикла, не нажимайте: 3 мс
  • Во время цикла, не нажимайте: 4 мс
  • Цикл Util, без нажатия: 4 мс
  • Util loop, нажмите: 5 мс

В основном, когда вы получаете более 10 000 предметов, вы начинаете видеть реальную разницу. Таким образом, от 0 до 10 000 наименований не имеет значения, какой вы используете.

package
{
    public class Loops{
        public static function forLoop(vector:Vector.<Foo>, usePush:Boolean = false):Array{
            var result:Array = [];

            for(var i:int = 0; i < vector.length; i++){
                if(usePush){
                    result.push(vector[i]);
                }else{
                    result[result.length] = vector[i];
                }
            }

            return result;          
        }

        public static function foreachLoop(vector:Vector.<Foo>, usePush:Boolean):Array{
            var result:Array = [];

            for each(var key:String in vector){
                if(usePush){
                    result.push(vector[key]);
                }else{
                    result[result.length] = vector[key];
                }
            }

            return result;          
        }

        public static function whileLoop(vector:Vector.<Foo>, usePush:Boolean):Array{
            var result:Array = [];

            var i:int = 0;
            while(i < vector.length){
                if(usePush){
                    result.push(vector[i]);
                }else{
                    result[result.length] = vector[i];
                }
            }

            return result;                      
        }

        public static function arrayUtilLoop(vector:Vector.<Foo>, usePush:Boolean):Array{
            var result:Array = [];

            function arrayUtilForeach(element:*, index:int, array:Array):void{
                if(usePush){
                    array.push(element);
                }else{
                    array[result.length] = element;
                }
            }           

            vector.forEach(arrayUtilForeach);

            return result;          
        }
    }
}

Я использовал функцию getTimer, чтобы выполнить эталонный тест, поэтому он может быть не точным на 100%, но разница между циклами настолько велика, что я не думаю, что это имеет значение.

Надеюсь, кто-то нашел это полезным.

6 голосов
/ 13 марта 2012

использование:

var myArray:Array = [];
myArray.push.apply(null, myVector);

или

var myArray:Array = new Array().concat(myVector);
3 голосов
/ 08 августа 2012

Второй ответ Vaukalak не только работает, но и намного быстрее, чем ответ с верхним голосом, я его немного помассировал, так как [] дает значительно более быстрое построение массива, чем new Array (). Ниже также представлен лучший способ создания вектора из массива.

// make a Vector from an array
var toVector : Vector.<String> = Vector.<String>(['a','b','c']) 

// populate an array from a Vector
var toArray : Array = [].concat(toVector);

Обратите внимание, что похоже, что это работает только со вспышкой 11

3 голосов
/ 07 ноября 2011

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

    private var _vector:*;

    public function VectorUtil(vector:*)
    {
        _vector = vector;
    }

    public function toArray():Array
    {
        var a:Array = [];
        for (var i:int = 0; i < _vector.length; ++i)
            a.push(_vector[i]);
        return a;
    }
0 голосов
/ 02 июня 2011

var a: Array = some_vector as Array;

0 голосов
/ 21 июня 2010

Если у вас есть вектор строк, вы можете сделать:

myArray = myVec.join(",").split(",");

для быстрого и грязного преобразования массива.

0 голосов
/ 11 сентября 2009

вызов функции для каждого элемента в векторе будет намного медленнее, особенно в более длинном векторе. однако эти примеры, вероятно, все эквивалентны, если только вы не имеете дело с довольно длинным вектором / массивом - удобочитаемость и простота использования, как правило, важнее, чем оптимизация.

при этом, я думаю, самый быстрый способ - использовать цикл while с итератором по сравнению с 0.

var myArray:Array = new Array(myVector.length);
var i:int=myVector.length;
while (i--) {
    myArray[i] = myVector[i];
}

к сожалению, вы не можете внедрить эту технику в метод для простоты повторного использования, потому что нет способа указать параметр метода Vector общего базового типа ....: (*

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...