获取 ActionScript 3 字典的大小

Posted

技术标签:

【中文标题】获取 ActionScript 3 字典的大小【英文标题】:Get size of ActionScript 3 Dictionary 【发布时间】:2011-01-24 02:43:11 【问题描述】:
var d:Dictionary = new Dictionary();
d["a"] = "b";
d["b"] = "z";

如何获取字典的长度/大小(为2)?

【问题讨论】:

【参考方案1】:

没有内置方法可以获取 AS3 字典的大小/长度/计数。 有一些解决方法:例如,您可以创建一个自定义字典类,它扩展或包装flash.utils.Dictionary 类,添加计数器功能。您可以在添加/删除条目时管理计数,或者使用简单的 For 循环迭代按需计数:

public static function countKeys(myDictionary:flash.utils.Dictionary):int 

    var n:int = 0;
    for (var key:* in myDictionary) 
        n++;
    
    return n;

【讨论】:

太糟糕了,不得不构建一个包装器。 有必要避免 For 循环中的陷阱,即使用 for..in 循环遍历数组时会发生什么。 仍然可以提供一个内置的 DictionaryUtils 类。【参考方案2】:

理想情况下,只需在 Dictionary 周围实现一个包装器,该包装器扩展了 Proxy 类。这允许您覆盖和拦截 Dictionary 中属性的添加和删除,允许使用新的 Dictionary 类与原始类完全一样,具有完全相同的语法和能力,并添加一个返回数量的长度函数键。

此实现的工作原理如下。当设置或删除一个属性时,它会检查该属性是否已经存在(是否严格等于未定义)并相应地增加或减少内部长度计数器。当条目的值设置为 undefined 以保持一致性时,此实现还会自动删除条目。

我为这个问题编写了这个 Dictionary 包装器;大约花了 5 分钟,它提供了一个返回长度的长度函数。我选择使它成为一个函数而不是一个属性,这样它就不会干扰属性名称或字典属性的枚举。

请勿使用此实现;改用跟随它的那个。我在下面解释原因。

package flos.utils 

    import flash.utils.flash_proxy;
    import flash.utils.Proxy;

    public class Dictionary extends Proxy
    
        private var d:flash.utils.Dictionary;
        private var _length:int = 0;

        public function Dictionary( weakKeys:Boolean = false ) 
        
            d = new flash.utils.Dictionary( weakKeys );
        

        public function length():int
        
            return _length;
        

        override flash_proxy function getProperty(name:*):* 
        
            return d[name];
        

        override flash_proxy function setProperty(name:*, value:*):void 
        
            if (value === undefined) //delete property when explicitly set to undefined, to enforce rule that an undefined property does not exist and is not counted
            
                delete this[name];
                return;
            
            if (d[name] === undefined)
                _length++;
            d[name] = value;
        

        override flash_proxy function deleteProperty(name:*):Boolean 
        
            if (d[name] !== undefined)
            
                delete d[name];
                _length--;
                return true;
            
            return false;
        
    

免责声明:上面的实现虽然是理论上可行的最有希望的方法,但最终是死路一条,因为 Dictionary 本质上与 Pr​​oxy 接口方法不兼容。

首先,setPropertygetPropertydeleteProperty 方法似乎接收无类型的 name 参数,但它们实际上是强类型的 QName 对象,这实际上将您的键限制为 String 类型名称,就像Object 和关联数组一样。 Dictionary 不受此限制的约束,允许使用对象实例作为唯一键,因此它与 Proxy 类方法本质上是不兼容的。 Dictionary 类的文档也有一个注释,它明确指出 QName 对象不能用作键。

同样,Proxy 的nextName 方法会阻止您枚举所有Dictionary 键,原因相同,因为它具有强类型返回值String。因此,即使setPropertygetProperty 实际上接受了名称的无类型键,您仍然无法通过枚举检索它们,因为nextName 方法仅返回类型字符串。 Dictionary 只是属于它自己的一个类。

您可以做的最好的事情是实现一个像上面这样的包装器,它公开底层字典以进行枚举,但其他人需要使用非类型化名称和值调用显式 addKey/removeKey 方法,而不是使用代理行为。

鉴于以上所有情况,更好的实现如下,您可以通过调用 getValue/setValue/removeValue 等方法来操作字典,并可以访问键枚举和长度属性:

public class Dictionary

    private var d:flash.utils.Dictionary;
    private var _keys:Array;

    public function Dictionary( weakKeys:Boolean = false )
    
        d = new flash.utils.Dictionary( weakKeys );
        _keys = new Array();
    

    public function get keys():Array
    
        return _keys.concat(); //return copy of keys array
    

    public function get length():int
    
        return _keys.length;
    

    public function containsKey( key:* ):Boolean
    
        return d[key] !== undefined;
    

    public function setValue( key:*, value:* ):void
    
        if (value === undefined) //delete property when explicitly set to undefined, to enforce rule that an undefined property does not exist and is not counted
        
            removeValue( key );
            return;
        
        if (d[key] === undefined)
        
            _keys.push( key );
        
        d[key] = value;
    

    public function getValue( key:* ):*
    
        return d[key];
    

    public function removeValue( key:* ):Boolean
    
        if (d[key] !== undefined)
        
            delete d[key];
            var i:int = _keys.indexOf( key );
            if (i > -1)
                _keys.splice( i, 1 );
            return true;
        
        return false;
    

【讨论】:

【参考方案3】:

您可以使用 DictionaryUtil:

var dictionaryLength : int = DictionaryUtil.getKeys(d).length;

【讨论】:

以上是关于获取 ActionScript 3 字典的大小的主要内容,如果未能解决你的问题,请参考以下文章

ActionScript 3 在窗口的舒展背景调整大小

ActionScript 3 Flash调整Swf的大小

ActionScript 3 调整bitmapdata的大小

ActionScript 3 平滑位图调整大小

ActionScript 3 全屏图像调整大小(按比例)

ActionScript 3 AS3按比例调整大小