AS3: как преобразовать вектор в массив

Какой самый лучший способ преобразовать вектор в массив в 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 (), скрывающаяся где-то в стандартной библиотеке?

 rzetterberg10 июл. 2009 г., 14:36
Кроме того, используя myArray [myArray.length] = elem; быстрее, чем использование push ().
 Dykam10 июл. 2009 г., 11:04
for (var i: int; i & lt; muVector.length; ++ i) {} может быть быстрее. Но другого решения нет.

Ответы на вопрос(8)

Есть функция 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 (), и затем у вас есть этот код в этой функции, поэтому вам не нужно писать его каждый раз, когда вы хотите преобразовать.

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

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

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

For loop, not push: 520 ms For loop, push: 1027 ms Foreach loop, not push: 1753 ms Foreach loop, push: 2264 ms While loop, not push: 2775 ms While loop, not push: 3282 ms Util loop, not push: 4059 ms Util loop, push: 4570 ms

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

For loop, not push: 1 ms For loop, push: 2 ms Foreach loop, not push: 2 ms Foreach loop, push: 3 ms While loop, not push: 3 ms While loop, not push: 4 ms Util loop, not push: 4 ms Util loop, push: 5 ms

В основном, когда вы получаете более 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%, но между разными циклами существует такая большая разница, что я не думаю, что это имеет значение.

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

 10 июл. 2009 г., 14:35
да, на мой взгляд, это лучше, чем использование for / для каждого цикла. Это вызов функции для каждого элемента в векторе. Насколько медленнее именно этот подход?
 27 июл. 2011 г., 17:05
Вы не хотите вызывать myVector.length в каждом цикле. удалив его, я более чем удвоил производительность,pastebin.com/0waTqaER проверка длины каждый раз = 491 не проверка длины каждый раз = 209
 10 июл. 2009 г., 10:04
очень красиво, но очень медленно ... ты понимаешь, сколько звонков это делает?
 29 окт. 2014 г., 21:31
Просто примечание: для каждого не гарантируется какой-либо конкретный заказ:stackoverflow.com/questions/618966/… Хотя может быть так, что реализация as3 на самом деле ведет себя так, как хотелось бы.
 27 июл. 2011 г., 20:58
@gigawatts Отлично! Спасибо, что поделился :)

использовать:

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

или же

var myArray:Array = new Array().concat(myVector);
 06 окт. 2016 г., 13:39
Это создает одноэлементный массив с вектором в качестве первого значения ...

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

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

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

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

Решение Вопроса

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

edit:

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

function toArray(iterable:*):Array {
     var ret:Array = [];
     for each (var elem:Foo in iterable) ret.push(elem);
     return ret;
}
 04 авг. 2011 г., 22:17
@IQpierce: Ответ обновлен.
 04 авг. 2011 г., 22:05
Построение функции полезности не является опцией, поскольку она не может применяться к любому типу вектора ... если кто-то не знает, как создать функцию, которая принимает в качестве параметра ЛЮБОЙ тип вектора?

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

    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;
    }

var a: Array = some_vector as Array;

 25 сент. 2012 г., 17:22
Вектор не может быть преобразован в массив. Этот код вернул бы ноль.

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

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

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

 01 нояб. 2010 г., 18:36
Что если в ваших строках есть запятые?
 20 нояб. 2010 г., 16:09
разделитель не имеет значения, поэтому myVect.join (& quot;: |: & quot;). split (& quot;: |: & quot;) работает так же хорошо ...

Второй ответ Ваукалака не только работает, но и намного быстрее, чем ответ с верхним голосованием, я его немного помассировал, так как [] дает значительно более быстрое построение массива, чем 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);

Please note, this only seems to work with flash 11

 16 мая 2013 г., 19:57
Это фактически создает одноэлементный массив с вектором в качестве первого значения.
 05 февр. 2014 г., 19:40
Откуда у этого неправильного ответа столько голосов? Как указывает jameshfisher, поведение некорректно. StackOverflow превращается в троллинг?
 18 мар. 2014 г., 11:40
@ Джонатан, ответ на твой первый вопрос - это вопрос, связанный со вспышкой. Большинство сообщества очень младшие разработчики.

Ваш ответ на вопрос