用旧词典构建新词典?帮助字典递归

发布于 2024-09-17 16:50:04 字数 2314 浏览 5 评论 0原文

我正在使用大量分层分类术语,其中每个术语(“203”)在舞台上都有一个匹配的“term203”影片剪辑,并且无法使用递归函数返回给定术语的所有后代。

每个术语都有一个主要的 Dictionary() 对象,其中包含以下嵌套组织:

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

...其中 [object Movie Clip] 的实例名称为 “term203”。所有这些 object:subObjectArray 项(“terms”)都存储在主 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) 不起作用。请帮忙!

I'm working with a large set of hierarchical taxonomic terms, where each term ("203") has a matching "term203" movie clip on the stage, and am having trouble getting a recursive function to return all of a given term's descendants.

There is a main Dictionary() object with the following nested organization for each term:

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

...where the [object Movie Clip]'s instance name would be "term203". All of these object:subObjectArray items ("terms") are stored in a master taxonomy:Dictionary() object.

I've been trying to make a recursive function (which is in itself already a little above my head) that takes the click.target of a movie clip and returns a new Dictionary() object with all of the children and grandchildren and great grandchildren (etc) of that term, in the same, nested organization described above.

The code below traces the right number of recursive loops, but the returned Dictionary() object only contains the first run's terms (only the immediate children of the requested term).

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

I certainly do not claim to be the most efficient AS3 programmer, so I am open to alternative configurations. However, after trying static and nested Arrays, I would prefer to continue using the Dictionary() object as my main pool.

As noted, only the immediate children end up animating in the revealChildren() function. It's mystifying to me then, that in the getAllChildren() function, all of the descendants trace sequentially (well in no particular order) in the output window.

Also I can't get any sort of name or property out of the subSet Object. That could be the problem.

I've only tested it as far as 'two generations,' but it seems that only the first round of calling the function successfully adds those terms to the new Dictionary() object and returns it intact to the animating function.

Too bad dict.filter(getDescendants) won't work. Please help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

弥枳 2024-09-24 16:50:04

为了简化事情,我添加了一个名为 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:
In response to your comment... Your code originally said this after finding a child named element:

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

您在此处使 children[element] 等于 Dictionary 对象。您创建的是一个树结构,将 MovieClip 对象映射到包含其子级的类似映射的 Dictionary 对象。在此结构上使用 for in 循环只会为您提供顶级子级。它不会递归遍历整棵树。

To simplify things, I've added an output parameter called children. This is the Dictionary into which our function will store its results. It has a default value, so you don't need to specify one. In that case, it will create a new instance for itself.

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

When a child is discovered, it is copied over exactly: children[element] = taxonomy[element];
Next, the function calls itself recursively, supplying it the same output dictionary as it has been using.


Edit:
In response to your comment... Your code originally said this after finding a child named element:

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

You're making children[element] equal to a Dictionary object here. What you create is a tree structure, mapping MovieClip objects to Dictionary objects containing a similar mapping of its children. Using a for in loop on this structure will only give you the top-level children. It will not recursively traverse the entire tree.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文