Получить размер словаря ActionScript 3 - PullRequest
30 голосов
/ 05 марта 2010
var d:Dictionary = new Dictionary();
d["a"] = "b";
d["b"] = "z";

Как получить длину / размер словаря (который равен 2)?

Ответы [ 3 ]

32 голосов
/ 05 марта 2010

Нет встроенного метода для получения размера / длины / количества словаря 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;
}
0 голосов
/ 07 ноября 2017

Вы можете использовать DictionaryUtil:

var dictionaryLength : int = DictionaryUtil.getKeys(d).length;
0 голосов
/ 01 марта 2014

В идеале можно просто реализовать обертку вокруг Dictionary, которая расширяет класс Proxy.Это позволяет вам переопределять и перехватывать добавление и удаление свойств из словаря, позволяя использовать новый класс Dictionary точно так же, как и оригинал, с точно таким же синтаксисом и возможностями, с добавлением функции длины, которая возвращает числоkeys.

Эта реализация работает следующим образом.Когда свойство установлено или удалено, оно проверяет, существует ли свойство уже (равно ли оно строго неопределено), и соответственно увеличивает или уменьшает внутренний счетчик длины.Эта реализация также автоматически удаляет запись, когда ее значение установлено как неопределенное для согласованности.

Я написал эту словарь-обертку только для этого вопроса;это заняло около 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.

Во-первых, методы setProperty, getProperty и deleteProperty, кажется, получают нетипизированные name параметры, но на самом деле они являются строго типизированными QName объектами, которые по существу ограничивают ваши ключи String.введите имена, как Object и связанные массивы.Dictionary не ограничен этим ограничением и позволяет использовать экземпляры объекта в качестве уникальных ключей, поэтому он по своей сути несовместим с методами класса Proxy.Документация класса Dictionary также содержит одну заметку, в которой прямо указано, что объекты QName нельзя использовать в качестве ключей.

Аналогично, метод nextName Proxy не позволяет перечислять все ключи Dictionary дляПо той же причине, поскольку оно имеет возвращаемое значение строго типа String.Таким образом, даже если setProperty, getProperty фактически принимают нетипизированные ключи для имен, вы все равно не сможете получить их с помощью перечисления, потому что метод 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;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...