Строить новый словарь из старого? Помогите со словарем рекурсии - PullRequest
2 голосов
/ 31 августа 2010

Я работаю с большим набором иерархических таксономических терминов, где у каждого термина («203») есть соответствующий видеоклип «term203» на сцене, и у меня возникают проблемы с получением рекурсивной функции для возврата всех заданных потомки термина.

Существует основной Dictionary() объект со следующей вложенной организацией для каждого термина:

{ [object Movie Clip] : { "tid":203, "parent":99, "name":"Culture", selected:false, "otherData":"etc" } }

... где имя экземпляра [object Movie Clip] будет "term203". Все эти объекты: элементы subObjectArray («термины») хранятся в главном taxonomy:Dictionary() объекте.

Я пытался создать рекурсивную функцию (которая сама по себе уже немного выше моей головы), которая берет click.target фрагмента ролика и возвращает новый объект Dictionary() с все дети, внуки и правнуки (и т. д.) этого термина в одной и той же вложенной организации, описанной выше.

Приведенный ниже код отслеживает правильное количество рекурсивных циклов, но возвращенный объект Dictionary() содержит только термины первого запуска (только непосредственные потомки запрошенного термина).

var taxonomy:Dictionary = new Dictionary();

// ...Term info is loaded into taxonomy from a JSON-style text file)
// ...MOUSE_OVER event listeners are added to each

function revealChildren(hvr:MouseEvent):void {

    trace("Spotlighting " + taxonomy[hvr.target].name + "'s children...");

    for(var key:Object in getAllChildren(taxonomy[hvr.target].tid)) {
        trace("Animating " + taxonomy[key].tid); // Traces only immediate children
        var revealTween = new Tween(key, "alpha", Regular.easeInOut, key.alpha, 1, 1, true);
    }
}

function getAllChildren(origin):Dictionary {

    var children:Dictionary = new Dictionary();

    for(var element:Object in taxonomy) {
        if(taxonomy[element].parent == origin) {
            var subSet = getAllChildren(taxonomy[element].tid);
            children[element] = subSet; // *CAN'T ACCESS 'subSet' PROPERLY*
            trace("Parent = " + origin);
            trace("Matched! Adding " + taxonomy[element].tid + " as key and setting its value to " + subSet); // Traces correct amount of times, one for each descendent
        }
        else {
        }
    }
    return children;
}

Я, конечно, не претендую на звание самого эффективного программиста AS3, поэтому я открыт для альтернативных конфигураций. Однако после попытки использования статических и вложенных массивов я бы предпочел продолжить использование объекта Dictionary() в качестве основного пула.

Как отмечалось, только непосредственные дети заканчивают анимацию в функции revealChildren(). Тогда меня удивляет, что в функции getAllChildren() все потомки прослеживают последовательно (ну в произвольном порядке) в окне вывода.

Также я не могу получить какое-либо имя или свойство из объекта subSet. Это может быть проблемой.

Я тестировал его только как «два поколения», но кажется, что только первый раунд вызова функции успешно добавляет эти термины в новый объект Dictionary() и возвращает его нетронутым для функции анимации.

Жаль, dict.filter(getDescendants) не сработает. Пожалуйста, помогите!

1 Ответ

2 голосов
/ 31 августа 2010

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

function getAllChildren(origin:*, children:Dictionary = null):Dictionary {
    if (children = null) children = new Dictionary();

    for(var element:* in taxonomy) {
        if(taxonomy[element].parent == origin) {
            children[element] = taxonomy[element];
            getAllChildren(taxonomy[element].tid, children);
        }
    }
    return children;
}

Когда ребенок обнаружен, он копируется точно: children[element] = taxonomy[element];
Затем функция вызывает себя рекурсивно, предоставляя ей тот же выходной словарь, который использовался.

<ч /> Edit:
В ответ на ваш комментарий ... Ваш код первоначально сказал это после обнаружения ребенка по имени element:

children[element] = getAllChildren(taxonomy[element].tid);

Вы делаете children[element] равным Dictionary объекту здесь. То, что вы создаете - это древовидная структура, отображающая MovieClip объекты на Dictionary объекты, содержащие аналогичное отображение его дочерних элементов. Использование цикла for in в этой структуре даст вам только дочерних элементов верхнего уровня. Он не будет рекурсивно проходить по всему дереву.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...