flash - 获取ActionScript 3 Dictionary的大小





actionscript-3 hashtable (4)


你可以使用DictionaryUtil:

var dictionaryLength : int = DictionaryUtil.getKeys(d).length;
var d:Dictionary = new Dictionary();
d["a"] = "b";
d["b"] = "z";

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




没有内置方法来获取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;
}



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

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

我为这个问题写了这个字典包装器; 花了大约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本质上与Proxy接口方法不兼容。

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

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

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

鉴于上述所有情况,更好的实现方式如下,您可以通过调用getValue / setValue / removeValue等方法来操作字典,并且可以访问键枚举以及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;
    }



@ doc_180有正确的概念,除了他专注于数字,而原始海报有字符串的问题。

解决方案是更改mx.rpc.xml.XMLEncoder文件。 这是第121行

    if (content != null)
        result += content;

[我查看了Flex 4.5.1 SDK; 行号可能在其他版本中有所不同]

基本上,验证失败是因为'content为null',因此您的参数不会添加到传出的SOAP数据包中; 从而导致缺少参数错误。

您必须扩展此类以删除验证。 然后链上有一个大雪球,修改SOAPEncoder以使用修改后的XMLEncoder,然后修改Operation以使用修改后的SOAPEncoder,然后模拟WebService以使用备用Operation类。

我花了几个小时,但需要继续前进。 这可能需要一两天时间。

您可以只修复XMLEncoder行并进行一些猴子修补以使用您自己的类。

我还要补充一点,如果你切换到使用带有ColdFusion的RemoteObject / AMF,则传递null并没有问题。

11/16/2013更新

我最后一篇关于RemoteObject / AMF的评论还有一个新增内容。 如果您使用的是CF10; 然后从服务器端对象中删除对象上具有空值的属性。 因此,您必须在访问之前检查属性是否存在,否则您将收到运行时错误。 像这样检查:

<cfif (structKeyExists(arguments.myObject,'propertyName')>
 <!--- no property code --->
<cfelse>
 <!--- handle property  normally --->
</cfif>

这是CF9的行为变化; 其中null属性将变为空字符串。

编辑12/6/2013

由于存在关于如何处理空值的问题,因此这是一个快速示例应用程序,用于演示字符串“null”如何与保留字null相关联。

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" initialize="application1_initializeHandler(event)">
    <fx:Script>
        <![CDATA[
            import mx.events.FlexEvent;

            protected function application1_initializeHandler(event:FlexEvent):void
            {
                var s :String = "null";
                if(s != null){
                    trace('null string is not equal to null reserved word using the != condition');
                } else {
                    trace('null string is equal to null reserved word using the != condition');
                }

                if(s == null){
                    trace('null string is equal to null reserved word using the == condition');
                } else {
                    trace('null string is not equal to null reserved word using the == condition');
                }

                if(s === null){
                    trace('null string is equal to null reserved word using the === condition');
                } else {
                    trace('null string is not equal to null reserved word using the === condition');
                }

            }

        ]]>
    </fx:Script>
    <fx:Declarations>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
</s:Application>

跟踪输出是:

使用!=条件,null string不等于null保留字

使用==条件,null string不等于null保留字

使用===条件,null string不等于null保留字





flash actionscript-3 actionscript dictionary hashtable