通过递归遍历Javascript对象来累积路径

时间:2015-11-30 08:00:46

标签: javascript algorithm recursion

我有一个存储在Javascript对象中的树结构,我想从头部(sms_in)节点提取所有可能的路径到分支中的最后一个节点。以下是树结构的示例表示。

enter image description here

注意:任何给定节点都可以有n个输出('true'类型)连接但只有一个输入连接。我的意思是,当你想从sms_in节点转到isEmpty1节点时,只有一条路径[{ 'sms_in' : 'true'} ]。但是如果你想从isEmpty1转到dbInsert1,你必须选择false'路径,而不是&{39; true'路径。您也可以从isEmpty节点转到其他节点(在给定的情况下不是)。但是,您只能通过一条路径到达isEmpty节点,即通过' sms_in'节点。

    var graph =
{
    "metadata": {"id": "sms_in", "type": "api", "optionsDivId": "div_sms_in", "options": {}},
    "data": {
        "true": {
            "isEmpty1": {
                "metadata": {
                    "id": "isEmpty1",
                    "type": "empty",
                    "optionsDivId": "div_isEmpty1",
                    "options": {}
                },
                "data": {
                    "true": {
                        "sms1": {
                            "metadata": {
                                "id": "sms1",
                                "type": "api",
                                "optionsDivId": "div_sms1",
                                "options": {}
                            }, "data": {"true": {}, "false": false}
                        }
                    },
                    "false": {
                        "dbInsert1": {
                            "metadata": {
                                "id": "dbInsert1",
                                "type": "dbInsert",
                                "optionsDivId": "div_dbInsert1",
                                "options": {}
                            },
                            "data": {
                                "true": {
                                    "sms2": {
                                        "metadata": {
                                            "id": "sms2",
                                            "type": "api",
                                            "optionsDivId": "div_sms2",
                                            "options": {}
                                        }, "data": {"true": {}, "false": false}
                                    }
                                }, "false": false
                            }
                        }
                    }
                }
            }
        }, "false": false
    }
};

这里我有两种类型的节点,其中'if/empty'类型的节点具有'true/false'类型子节点,而所有其他节点仅具有'true'类型节点。我想以下列方式遍历节点并获取所有可能情况的完整路径。

var output = [

 [ {'sms_in':'true'}, {'isEmpty1':'true'}, {'sms1':''}],
 [{'sms_in':'true'}, {'isEmpty1':'false'}, {'dbInsert1':'true'}, {'sms2':''}]

];

我可以遍历树,但我不知道如何累积完整路径以获取数组格式的output。 有人可以帮我吗?

1 个答案:

答案 0 :(得分:1)

这个解决方案有效,但我不会依赖它,因为数据结构。

基本上你有这样的结构

data.true[k].data.true  --> { k: true }
data.true[k].data.false --> { k: false }
          ^   and   ^

这是非常罕见的。

sms1sms2的值在我的情况true而非''。想要的值不在给定的对象中。



function traverse(o, p, last) {
    var r = [];
    Object.keys(o).forEach(function (k) {
        var l = typeof o[k] === 'object' && Object.keys(o[k])[0],
            temp = {};
        temp[last] = k;
        if (l && o[k][l].data && typeof o[k][l].data === 'object') {
            r = r.concat(traverse(o[k][l].data, p.concat(temp), l));
        } else {
            o[k] && r.push(p.concat(temp));
        }
    });
    return r;
}

var graph = { "metadata": { "id": "sms_in", "type": "api", "optionsDivId": "div_sms_in", "options": {} }, "data": { "true": { "isEmpty1": { "metadata": { "id": "isEmpty1", "type": "empty", "optionsDivId": "div_isEmpty1", "options": {} }, "data": { "true": { "sms1": { "metadata": { "id": "sms1", "type": "api", "optionsDivId": "div_sms1", "options": {} }, "data": { "true": {}, "false": false } } }, "false": { "dbInsert1": { "metadata": { "id": "dbInsert1", "type": "dbInsert", "optionsDivId": "div_dbInsert1", "options": {} }, "data": { "true": { "sms2": { "metadata": { "id": "sms2", "type": "api", "optionsDivId": "div_sms2", "options": {} }, "data": { "true": {}, "false": false } } }, "false": false } } } } } }, "false": false } },
    path = traverse(graph.data, [], 'sms_in');

document.write('<pre>' + JSON.stringify(path, 0, 4) + '</pre>');
&#13;
&#13;
&#13;