我有一个存储在Javascript对象中的树结构,我想从头部(sms_in
)节点提取所有可能的路径到分支中的最后一个节点。以下是树结构的示例表示。
注意:任何给定节点都可以有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
。
有人可以帮我吗?
答案 0 :(得分:1)
这个解决方案有效,但我不会依赖它,因为数据结构。
基本上你有这样的结构
data.true[k].data.true --> { k: true }
data.true[k].data.false --> { k: false }
^ and ^
这是非常罕见的。
但sms1
和sms2
的值在我的情况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;