it-swarm.com.de

Größe des ActionScript 3-Wörterbuchs ermitteln

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

Wie erhalte ich die Länge/Größe des Wörterbuchs (die 2 ist)?

30

Es gibt keine integrierte Methode zum Abrufen der Größe/Länge/Anzahl eines AS3-Wörterbuchs. Es gibt Problemumgehungen: Sie können beispielsweise eine benutzerdefinierte Wörterbuchklasse erstellen, die die Klasse flash.utils.Dictionary erweitert oder umbrochen und die Leistungsindikatorfunktion hinzufügt. Sie können die Anzahl beim Hinzufügen/Entfernen von Einträgen oder bei Bedarf mithilfe einer einfachen For-Schleifen-Iteration verwalten:

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

Idealerweise würde man nur einen Wrapper um Dictionary implementieren, der die Proxy-Klasse erweitert. Auf diese Weise können Sie das Hinzufügen und Entfernen von Eigenschaften aus dem Dictionary außer Kraft setzen und abfangen. Auf diese Weise kann die neue Dictionary-Klasse mit genau der gleichen Syntax und den gleichen Fähigkeiten wie das Original verwendet werden, und es wird eine Längenfunktion hinzugefügt, die die Anzahl von zurückgibt Schlüssel.

Diese Implementierung funktioniert wie folgt. Wenn eine Eigenschaft festgelegt oder gelöscht wird, wird geprüft, ob sie bereits vorhanden ist (ob sie genau undefiniert ist), und der interne Längenzähler wird entsprechend inkrementiert oder dekrementiert. Diese Implementierung löscht einen Eintrag auch automatisch, wenn sein Wert aus Konsistenzgründen auf undefiniert gesetzt ist.

Ich habe diesen Dictionary-Wrapper nur für diese Frage geschrieben. Es dauerte ungefähr 5 Minuten und bietet eine Längenfunktion, die die Länge zurückgibt. Ich habe mich dafür entschieden, eine Funktion anstelle einer Eigenschaft zu verwenden, damit die Eigenschaftennamen oder die Aufzählung der Eigenschaften des Wörterbuchs nicht beeinträchtigt werden.

BENUTZEN SIE DIESE UMSETZUNG NICHT. BENUTZEN SIE DAS, DAS ES STATT FOLGT. Ich erkläre warum unten.

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

HAFTUNGSAUSSCHLUSS: Die obige Implementierung, obwohl der vielversprechendste Ansatz, der theoretisch hätte funktionieren können, ist letztendlich eine Sackgasse, da Dictionary von Natur aus nicht mit den Proxy-Schnittstellenmethoden kompatibel ist.

Erstens scheinen die Methoden setProperty, getProperty und deleteProperty untypisierte name-Parameter zu erhalten, es handelt sich jedoch tatsächlich um stark typisierte QName-Objekte, die Ihre Schlüssel im Wesentlichen auf String-Typnamen beschränken, genau wie Object und Arrays zuordnen. Dictionary ist nicht an diese Einschränkung gebunden und ermöglicht die Verwendung von Objektinstanzen als eindeutige Schlüssel. Daher ist es inhärent inkompatibel mit den Proxy-Klassenmethoden. Die Dokumentation der Dictionary-Klasse enthält auch eine einzige Anmerkung und besagt ausdrücklich, dass QName-Objekte nicht als Schlüssel verwendet werden können.

Ebenso verhindert die nextName-Methode von Proxy, dass Sie aus demselben Grund alle Dictionary-Schlüssel aufzählen, da sie den stark typisierten Rückgabewert String hat. Selbst wenn setProperty, getProperty tatsächlich untypisierte Schlüssel für die Namen akzeptiert, können Sie diese nicht über die Enumeration abrufen, da die Methode nextName nur den Typ string zurückgibt. Dictionary ist einfach eine Klasse für sich.

Das Beste, was Sie tun können, ist, einen Wrapper wie den oben beschriebenen zu implementieren, der das zugrunde liegende Wörterbuch für die Enumeration freigibt. Bei anderen ist jedoch der Aufruf expliziter addKey/removeKey-Methoden mit untypisierten Namen und Werten erforderlich, anstatt das Proxy-Verhalten zu verwenden.

In Anbetracht all der oben genannten Umstände wäre eine bessere Implementierung wie folgt, bei der Sie das Wörterbuch durch Aufrufen von Methoden wie getValue/setValue/removeValue manipulieren und Zugriff auf eine Schlüsselaufzählung sowie eine length-Eigenschaft haben:

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

Sie können DictionaryUtil verwenden:

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