flash actionscript-3 actionscript dictionary hashtable

flash - Obtener tamaño del diccionario de ActionScript 3



actionscript-3 dictionary (3)

var d:Dictionary = new Dictionary(); d["a"] = "b"; d["b"] = "z";

¿Cómo obtener la longitud / tamaño del diccionario (que es 2)?


Lo ideal es implementar un envoltorio alrededor del diccionario que amplíe la clase Proxy. Esto le permite anular e interceptar la adición y eliminación de propiedades del Diccionario, permitiendo que la nueva clase de Diccionario se use exactamente igual que el original, con la misma sintaxis y habilidades, con la adición de una función de longitud que devuelve el número de llaves.

Esta implementación funciona de la siguiente manera. Cuando se establece o borra una propiedad, se verifica si la propiedad ya existe (si es estrictamente igual a indefinida) y se incrementa o disminuye el contador interno de la longitud en consecuencia. Esta implementación también elimina automáticamente una entrada cuando su valor se establece en indefinido para la coherencia.

Escribí este envoltorio de diccionario solo para esta pregunta; tomó aproximadamente 5 minutos, y proporciona una función de longitud que devuelve la longitud. Elegí hacerlo una función en lugar de una propiedad para que no interfiera con los nombres de propiedad o la enumeración de las propiedades del diccionario.

NO USE ESTA IMPLEMENTACIÓN; UTILIZA EL QUE LO SIGUE EN LUGAR. Explico por qué a continuación.

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

DESCARGO DE RESPONSABILIDAD: La implementación anterior, aunque el enfoque más prometedor que podría haber funcionado en teoría, es en última instancia un callejón sin salida, ya que el diccionario es intrínsecamente incompatible con los métodos de la interfaz Proxy.

En primer lugar, los getProperty setProperty , getProperty y deleteProperty parecen recibir parámetros de name tipo, pero en realidad son objetos QName fuertemente tipados, que esencialmente restringen las claves a nombres de tipo String , al igual que Object y Asociar matrices. Dictionary no está sujeto a esta limitación y permite usar instancias de objeto como claves únicas, por lo que es inherentemente incompatible con los métodos de clase Proxy. La documentación de la clase Dictionary también tiene una sola nota, y establece explícitamente que los objetos QName no se pueden usar como claves.

Del mismo modo, el método nextName de Proxy evita que enumere todas las claves del Dictionary por la misma razón, ya que tiene un valor de retorno de String muy fuerte. Por lo tanto, incluso si setProperty , getProperty realmente acepta claves sin tipo para los nombres, aún no podrá recuperarlas a través de la enumeración porque el método nextName solo devuelve el tipo de cadena. Dictionary es simplemente una clase propia.

Lo mejor que puede hacer es implementar un contenedor como el anterior que expone el diccionario subyacente para la enumeración, pero otros requieren llamar a los métodos addKey / removeKey explícitos con nombres y valores sin tipo, en lugar de usar el comportamiento del Proxy.

Teniendo en cuenta todo lo anterior, una mejor implementación sería la siguiente, donde manipular el diccionario llamando a métodos como getValue / setValue / removeValue, y tener acceso a una enumeración de teclas, así como una propiedad de longitud:

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


Puedes usar DictionaryUtil:

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


No hay un método incorporado para obtener el tamaño / longitud / conteo de un diccionario AS3. Hay soluciones: por ejemplo, puede crear una clase de diccionario personalizada que amplíe o ajuste la clase flash.utils.Dictionary , agregando la funcionalidad del contador. Puede administrar el recuento a medida que las entradas se agregan / eliminan, o contar a pedido usando una iteración For loop simple:

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