迭代数据结构

时间:2015-10-30 17:31:17

标签: actionscript-3 recursion tree

我有点想知道如何遍历我的数据对象。我已经创建了一个递归函数来迭代XML元素并基本上输出与对象相同的结构,使用元素中的属性作为键,它拥有它自己的对象。从概念上讲,该对象看起来像这样。它是一种树,但我没有使用flex树,只是as3。

enter image description here

我想要了解的是每个"分支"有许多孩子,所以我不能硬编码每个分支的深度。

我想要完成的事情

我的数据结构中的每个节点都是文件夹名称,我需要将所有子节点附加到单个字符串中并存储它。为了生成"资产",我需要来自这些初始节点中的每一个的字符串(在示例图片中,它们是1,2,4,5,6和17)。因此,我需要遍历每个分支并返回与之前不同的集合,以便找到每个可能的资产组合。

从概念上讲,我知道我需要抓住"第一个指数"每个分支,将所有这些字符串输出到一个资产,然后将第一个分支向上移动一个"索引"直到它达到它的极限,这会触发下一个分支移动它的"索引"。但是,我实际上如何做到这一点对我来说有点神秘。

我是否需要将我的数据树重组为可以通过索引引用的数组,或者是否有一些更简单的方法来迭代我缺少的每个可能的组合。

我使用的是动作脚本3,但我并没有专门寻找代码示例,只是伪代码很好。

1 个答案:

答案 0 :(得分:1)

因为你试图将每棵树的N'拉成一个单独的字符串数组,所以在第一次传递中首先将这些树提取到它们的连续集(用它们的连接)会更容易。然后第二遍构建您想要的“资产”数组。由于文档的性质可能差别很大,我在下面创建了一个演示数据源。您可以运行以下代码,它将产生以下结果:

An Array of arrays of concatenated strings

//Assume the following structure.
var data:Array = [
    {
        "path":"one",
        "sub":[
            {
                "path":"seven",
                "sub":[
                    {"path":"nine.png"},
                    {"path":"ten.png"}
                ]
            },
            {
                "path":"eight",
                "sub":[
                    {"path":"eleven.png"},
                    {"path":"twelve.png"}
                ]
            }
        ]
    },
    {
        "path":"two",
        "sub":[
            {"path":"thirteen.png"},
            {"path":"fourteen.png"},
            {"path":"fifteen.png"},
            {"path":"sixteen.png"}
        ]
    },
    {
        "path":"four",
        "sub":[
            {
                "path":"seventeen",
                "sub":[
                    {"path":"nineteen.png"},
                    {"path":"twenty.png"}
                ]
            },
            {
                "path":"twenty-two",
                "sub":[
                    {"path":"twenty-one.png"},
                    {"path":"twenty-two.png"}
                ]
            }
        ]
    },
    {
        "path":"five",
        "sub":[
            {"path":"twenty-three.png"}
        ]
    },
    {
        "path":"six",
        "sub":[
            {
                "path":"twenty-four",
                "sub":[
                    {"path":"twenty-six.png"},
                    {"path":"twenty-seven.png"}
                ]
            },
            {
                "path":"twenty-nine",
                "sub":[
                    {"path":"twenty-eight.png"},
                    {"path":"twenty-nine.png"}
                ]
            }
        ]
    },
    {
        "path":"seventeen",
        "sub":[
            {"path":"thirtee.png"}
        ]
    }
]

function init():void {
    var sets:Array = [];

    // First we'll create a complete sequence of concatenated strings per set
    for (var i:int = 0; i < data.length; i++) {
        sets[i] = [];
        scan(data[i], sets[i]);
    }

    // Find the max length
    var max:int = 0, a:Array;
    for each (a in sets) {
        max = (a.length > max) ? a.length : max;
    }

    // Now we'll create our ordered assets, pulling out the firsts, then the seconds, and so on...
    var assets:Array = [];
    for (i = 0; i < max; i++) {
        assets[i] = [];

        for each (a in sets) {
            if (i < a.length) {
                assets[i].push(a[i]);
            }
        }
    }
}

function scan(node:Object, a:Array, prefix:String = ""):void {
    var subNode:Object;
    // This is a recursive function which digs till it finds no more sub properties.
    if (node.hasOwnProperty("sub")) {
        // On every sub node, it passes the currently concatenated path so far
        for each (subNode in node.sub) {
            scan(subNode, a, prefix + "/" + node.path);
        }
    } else {
        // When we reach the final depth, we can begin populating our array with paths.
        a.push(prefix + "/" + node.path);
    }
}

init();