Как проверить, является ли объект вектором? - PullRequest
5 голосов
/ 20 февраля 2011

Я хочу проверить, является ли объект вектором, любым вектором, а не только вектором одного типа.

Я провел тест:

var v:Vector.<int> = new Vector.<int>();
v.push(3);
v.push(1);
v.push(2);
trace(v is Array); // false
trace(v is Vector); // false
trace(v is Vector.<int>); // true
trace(v is Vector.<*>); // false

Кажется, что единственное, что возвращает true, это то, что указывает тип вектора, но я хочу проверить его на ЛЮБОЙ тип.

Мне понадобится очень эффективный метод сравнения, потому что getQualifiedClassName слишком медленный.

Мой текущий подход:

private static function isVector(obj:Object):Boolean {
    return (getQualifiedClassName(obj).indexOf('__AS3__.vec::Vector') == 0);
}

Но это в 2 раза медленнее, чем оператор is.

Мне нужна скорость, потому что она предназначена для класса сериализации объектов, и она должна быть очень быстрой.

Ответы [ 7 ]

7 голосов
/ 04 октября 2012

Проблема в том, что Vector. <*> - это другой класс, чем тот, который используется для , или . Числовые примитивы имеют специальные классы для лучшей эффективности. String и Boolean также являются примитивами, но в отличие от числовых примитивов они обнаруживаются <*>. В результате вам нужно только проверить общий вектор и 3 числовых типа.

Это решение в 2 раза быстрее, чем getQualifiedClassName, в худшем случае, когда объект не является вектором или вектором. и в 5 раз быстрее, если объект является непримитивным базовым типом Vector , как Вектор. :

return (obj is Vector.<*> 
     || obj is Vector.<Number>
     || obj is Vector.<int>
     || obj is Vector.<uint>);

Вот упрощенный тест:

var moo:Vector.<uint> = new Vector.<uint>();
var timer:Timer = new Timer();
var b:Boolean;
timer.startTimer();
for (var i:int = 0; i < 1000000; i++)
{
    b = (moo is Vector.<*> 
      || moo is Vector.<Number> 
      || moo is Vector.<int>
      || moo is Vector.<uint>);
}
logger.info("  is timer: " + timer.endTimer());

timer.startTimer();
for (i = 0; i < 1000000; i++)
{
    b = (flash.utils.getQualifiedClassName(moo).indexOf('__AS3__.vec::Vector') == 0);
}
logger.info("gqcn timer: " + timer.endTimer());


[LOG] com.tcg.test:   is timer: 320
[LOG] com.tcg.test: gqcn timer: 756

Изменить moo на Vector. :

[LOG] com.tcg.test:   is timer: 158
[LOG] com.tcg.test: gqcn timer: 743
1 голос
/ 25 февраля 2011

Другие методы слишком неэффективны, поэтому я все еще использую свой подход:

private static function isVector(obj:Object):Boolean {
    return (getQualifiedClassName(obj).indexOf('__AS3__.vec::Vector') == 0);
}
0 голосов
/ 20 июля 2016
private function getIsVector(obj:Object):Boolean
{
    return String(obj.constructor).indexOf('[class Vector.<*>]') == 0;
}
0 голосов
/ 08 июня 2016
    /// Return Class of any Target
    static public function getClass( Target:* ):Class
    {
        return getDefinitionByName ( getQualifiedClassName( Target ) ) as Class ;
    }

    /// Check if object is type of Vector.< * >
    static public function isVector( any:* ):Boolean 
    {
        return String( getClass( any ) ).indexOf( "[class Vector.<" ) > -1;
    }

    /// Get Vector < Class >
    static public function getVectorType( vector:* ):Class
    {
        var c:String = String( getClass( vector ) );
        var s:int = c.indexOf( '<' ) + 1;
        var e:int = c.indexOf( '>' );
        return getDefinitionByName( c.substring( s, e ) ) as Class;
    }
0 голосов
/ 18 августа 2015

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

(obj as Vector.<*>) is Vector.<*>
0 голосов
/ 20 февраля 2011

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

  1. v is ... (простые типы данных)
  2. v is ... (типы объектов, которые не являются коллекциями)
  3. v is Array
  4. v is XMLList
  5. v is ... (все другие типы коллекций, которые вы можете придумать)
  6. если ничего из вышеперечисленного не соответствует действительности, это должен быть вектор
  7. сериализует объекты в векторе. Если у вас более одного типа, это Vector.<*>, в противном случае установите тип вектора в соответствии с типом объекта элементов содержимого.
0 голосов
/ 20 февраля 2011
trace(new Array().fixed);//undefined
trace(new Object().fixed);//undefined
trace(new Vector.<Sprite>().fixed);//false
trace(new Vector.<*>().fixed);// false
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...