English 中文(简体)
2. 行动大体 3 理论
原标题:Get size of ActionScript 3 Dictionary
var d:Dictionary = new Dictionary();
d["a"] = "b";
d["b"] = "z";

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

最佳回答

There is no built-in method to get the size/lenght/count of an AS3 dictionary. There are workarounds: for example, you can create a custom dictionary class which extends or wraps the flash.utils.Dictionary class, adding the counter functionality. You can manage the count as entries are added/removed, or count on-demand using a simple For loop iteration:

public static function countKeys(myDictionary:flash.utils.Dictionary):int 
{
    var n:int = 0;
    for (var key:* in myDictionary) {
        n++;
    }
    return n;
}
问题回答

理想情况下,应该只需在 Dictionary 周围实现一个扩展 Proxy 类的包装器。这样可以覆盖和拦截对 Dictionary 的属性添加和删除操作,使得新的 Dictionary 类可以像原始类一样使用,具有完全相同的语法和能力,同时增加一个返回键数的长度函数。

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

我为了回答这个问题编写了这个字典包装器;它需要大约5分钟,提供一个返回长度的长度函数。我选择将其作为函数而不是属性,以避免干扰属性名称或对字典属性的枚举。 我为了回答这个问题编写了这个字典包装器;它需要大约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;
        }
    }
}

免责声明:上述实现虽然在理论上是最有前途的方法,但最终是一条死路,因为字典在本质上与代理接口方法不兼容。

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

同样地,代理的nextName方法也基于相同原因阻止您枚举所有Dictionary键,因为它具有强类型返回值String。因此,即使setPropertygetProperty实际上接受未类型化的名称键,您仍然无法通过枚举检索它们,因为nextName方法仅返回字符串类型。 Dictionary处于自己的类别。

你可以实现一个类似上面的包装器,将底层字典暴露出来以进行枚举,但其他操作需要调用显示的addKey/removeKey方法,使用未强制类型化的名称和值,而不是使用代理行为。

考虑到上述情况,更好的实现方式为,通过调用getValue/setValue/removeValue等方法来操作字典,同时可以访问keys枚举和length属性。

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

你可以使用 DictionaryUtil:

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




相关问题
Anagram Hash Function

I know something like this has been asked before, but the answer was sort of side tracked. I want to develop a hash function which will take a word and spit out an address of an array. So, for ...

Frequently Used metadata Hashmap

Are there any implementations of a static size hashtable that limits the entries to either the most recently or most frequently used metadata? I would prefer not to keep track of this information ...

热门标签