2015-11-30 72 views
0

我有一個存儲在Javascript對象中的樹結構,我想從頭部(sms_in)節點提取所有可能的路徑到分支中的最後一個節點。以下是樹結構的示例表示。通過遞歸遍歷一個Javascript對象來累積路徑

enter image description here

注意:任何給定的節點可以具有n個輸出('true'型)連接的,但只有一個輸入連接。我的意思是,當你想從sms_in節點到isEmpty1節點,只有一個路徑[{ 'sms_in' : 'true'} ]。但是,如果您想從isEmpty1dbInsert1,則必須選擇'false'路徑,而不是'true'路徑。你也可以去isEmpty節點的其他節點(不是在給定的情況下)。但是,您只能從一個路徑(即通過「sms_in」節點)到達isEmpty節點。

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

在這裏,我有2種類型的節點,其中'if/empty'類型的節點有'true/false'類型的子節點,而所有其他節點只有'true'類型的節點。我想遍歷節點並按照以下方式獲取所有可能情況的完整路徑。

var output = [ 

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

]; 

我可以遍歷樹,但我不知道如何積累得到output陣列形式的完整路徑。 有人可以幫我嗎?

+0

還是不明白你要完成的任務。從頭到特定的葉節點只有一條可能的路徑,所以我不明白「所有可能的路徑」意味着什麼,或者你試圖積累什麼結果。而且,你將什麼定義爲「尾節點」? – jfriend00

+0

@ jfriend00我對問題進行了編輯,請現在檢查問題。 – Fawzan

+0

首先,只有一個頭節點,對吧?然後,我不明白你的意思是「尾節點」。請描述。那麼,對於一個給定的「尾節點」,只有一條路可以到達那裏?或者你的意思是不同的「尾節點」?仍然不理解。什麼是路徑?什麼是尾節點?如何有多條路徑? – jfriend00

回答

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>');

+0

你說的數據結構是非常罕見的。你能幫我改善嗎? – Fawzan

+0

我不知道,數據應該是什麼目的。 –

+0

好吧,我的要求建議我創建一個像圖像中的決策樹,只有兩種類型的子有錯誤類型的分支。這就是爲什麼我想出了這個結構。 – Fawzan