How to check if an object is a Vector?

by yonatan
♥0 | Line 61 | Modified 2011-01-02 06:04:33 | MIT License
play

ActionScript3 source code

/**
 * Copyright yonatan ( http://wonderfl.net/user/yonatan )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/ipEg
 */

// Is there a fast(er) way to check if an object is a Vector of *any* type?

// Update: playerglobal.swc contains 4 vector classes:
//
// __AS3__.vec:Vector$object extends :Object 
// __AS3__.vec:Vector$int extends :Object 
// __AS3__.vec:Vector$uint extends :Object 
// __AS3__.vec:Vector$double extends :Object 
//
// Apparently everything that's not an int, uint or Number is covered by checking for Vector.<*> (see isVector4 function).
// Performance is better using getQualifiedClassName (isVector2) though.
//
// https://mail.mozilla.org/pipermail/tamarin-devel/2010-May/001423.html

package {
    import com.actionscriptbible.Example;
    import flash.display.*;
    import flash.utils.*;

    public class FlashTest extends Example {
        public function FlashTest() {
            test("isVector1 - Checking with 'is Vector' statment:", isVector1);
            test("isVector2 - Checking with getQualifiedClassName:", isVector2);
            // doesn't work - test("isVector3 - Checking with 'instanceof Vector' statment:", isVector3);
            test("isVector4 - Checking with 'is Vector<* || int || uint || Number>' statments:", isVector4);
            test("isVector5 - Checking with 'is Vector<*>' statment:", isVector5);

            benchmark("isVector2 time: ", isVector2);
            benchmark("isVector4 time: ", isVector4);
        }

        private var vi:Vector.<int> = new Vector.<int>;
        private var va:Vector.<*> = new Vector.<*>;
        private var vs:Vector.<Sprite> = new Vector.<Sprite>;
        private var vn:Vector.<Number> = new Vector.<Number>;
        private var s:String = "hoge";

        private function test(msg:String, fn:Function):void {
            trace(msg);
            trace("Vector.<int> (should be true): ", fn(vi));
            trace("Vector.<*> (should be true): ", fn(va));
            trace("Vector.<Sprite> (should be true): ", fn(vs));
            trace("Vector.<Number> (should be true): ", fn(vn));
            trace("String (should be false): ", fn(s));
            trace();
        }
        
        private function benchmark(msg:String, fn:Function):void {
            var t:Number = getTimer();

            for(var cnt:int = 100000; cnt; cnt--) {
                fn(vi); fn(va); fn(vs); fn(vn); fn(s);
                fn(vi); fn(va); fn(vs); fn(vn); fn(s);
                fn(vi); fn(va); fn(vs); fn(vn); fn(s);
                fn(vi); fn(va); fn(vs); fn(vn); fn(s);
                fn(vi); fn(va); fn(vs); fn(vn); fn(s);
                fn(vi); fn(va); fn(vs); fn(vn); fn(s);
                fn(vi); fn(va); fn(vs); fn(vn); fn(s);
                fn(vi); fn(va); fn(vs); fn(vn); fn(s);
                fn(vi); fn(va); fn(vs); fn(vn); fn(s);
                fn(vi); fn(va); fn(vs); fn(vn); fn(s);
            }

            trace(msg, getTimer() - t);
        }

        // This doesn't work
        private function isVector1(x:*):Boolean {
            return(x is Vector);
        }
        
        // This works, but I'm looking for something faster.
        // from http://stackoverflow.com/questions/2697671
        private function isVector2(x:*):Boolean {
            var class_name:String = getQualifiedClassName(x);
            return class_name.indexOf("__AS3__.vec::Vector.") === 0;
        }

        // This doesn't work
        private function isVector3(x:*):Boolean {
            return(x instanceof Vector);
        }

        // This seems to be working properly!!
        private function isVector4(x:*):Boolean {
            return(x is Vector.<*> || x is Vector.<int> || x is Vector.<uint> || x is Vector.<Number>);
        }

        // This doesn't work
        private function isVector5(x:*):Boolean {
            return(x is Vector.<*>);
        }
    }
}