如何测试一个对象是否是一个向量?

时间:2011-02-20 00:16:58

标签: actionscript-3

我想测试对象是否是向量,任何向量,而不仅仅是单个类型的向量。

我跑了一个测试:

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

但它比is运算符慢2倍。

我需要速度,因为它是一个对象序列化类,它需要非常快。

7 个答案:

答案 0 :(得分:7)

问题在于Vector。&lt; *&gt;与用于&lt; Number&gt;,&lt; int&gt;或&lt; uint&gt;的类别不同。数字原语具有特殊类以提高效率。字符串和布尔值也是基元,但与数字基元不同,它们由&lt; *&gt;检测。因此,您只需要测试通用Vector和3种数字类型。

此解决方案的速度是getQualifiedClassName的2倍,在最坏的情况下,对象不是Vector,或者是Vector。&lt; uint&gt;,如果对象是非原始基类型,则快5倍矢量,像Vector。&lt; Object&gt;:

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。&lt; Object&gt;:

[LOG] com.tcg.test:   is timer: 158
[LOG] com.tcg.test: gqcn timer: 743

答案 1 :(得分:1)

其他方法效率太低,所以我仍在使用我的方法:

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

答案 2 :(得分:0)

trace(new Array().fixed);//undefined
trace(new Object().fixed);//undefined
trace(new Vector.<Sprite>().fixed);//false
trace(new Vector.<*>().fixed);// false

答案 3 :(得分:0)

如果您需要对任何类型的对象进行序列化,您必须迭代所有可能的类型,因此您可以使用顺序方法来查找向量类型:

  1. v is ...(简单数据类型)
  2. v is ...(非集合的对象类型)
  3. v is Array
  4. v is XMLList
  5. v is ...(您可以想到的所有其他集合类型)
  6. 如果上述情况均不属实,则必须为向量
  7. 序列化向量中的对象。如果您有多个类型,则为Vector.<*>,否则根据内容项的对象类型设置向量类型。

答案 4 :(得分:0)

使用

(obj as Vector.<*>) is Vector.<*>

答案 5 :(得分:0)

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

答案 6 :(得分:0)

private function getIsVector(obj:Object):Boolean
{
    return String(obj.constructor).indexOf('[class Vector.<*>]') == 0;
}