2016-05-20 55 views
3

我試圖從列表中創建樹。我的數據就像;從js數組創建樹

A-->B-->C-->D-->E.. 
A-->B-->C-->D-->F.. 
A-->F-->C-->D-->E.. 
. 
. 
. 

我在array.I所有可能的數據路徑要顯示此像

     A 
         -B 
         -C 
          -D 
           -E 
           -F 
         -F 
         -C 
          -D 
          -E 

如何創建和使用javascript檢查?我需要createTreeFunction :)

function parseData(data) 
    { 


    $.each(data, function (i, p) { 
        var arr = p.split("--->"); 

       createTreeFunction(p); 

        }); 

    }; 
    function parseData(data) 
     { 


     $.each(data, function (i, p) { 
         var arr = p.split("--->"); 

        createTreeFunction(p); 

         }); 

    }; 
+2

= Java和它說的Javascript,在這個網站上無數地方。 –

+0

請提供一些無效的數據(樹智慧),或創建一個循環。請使用唯一標識符。 –

回答

0

對於這個用例,我發明了非常有用的兩個Object方法;即Object.prototype.getNestedValue()Object.prototype.setNestedValue()。通過利用這些方法,這項工作只不過是一個單線程的JS代碼。見下文......

Object.prototype.getNestedValue = function(...a) { 
 
    return a.length > 1 ? (this[a[0]] !== void 0 && this[a[0]].getNestedValue(...a.slice(1))) : this[a[0]]; 
 
}; 
 
Object.prototype.setNestedValue = function(...a) { 
 
    return a.length > 2 ? typeof this[a[0]] === "object" && this[a[0]] !== null ? this[a[0]].setNestedValue(...a.slice(1)) 
 
                       : (this[a[0]] = typeof a[1] === "string" ? {} : new Array(a[1]), 
 
                       this[a[0]].setNestedValue(...a.slice(1))) 
 
         : this[a[0]] = a[1]; 
 
}; 
 

 
var data = "A-->B-->C-->D-->E\nA-->B-->C-->D-->F\nA-->F-->C-->D-->E", 
 
    datarr = data.split("\n").map(e => e.split("-->")), // get your list in an array 
 
     o = {}; 
 
datarr.forEach(a => !o.getNestedValue(...a) && o.setNestedValue(...a,null)); 
 

 
console.log(JSON.stringify(o,null,2));

2

基本上可以使用至少兩種不同的結構爲孩子用於構建樹,一個以與陣列(溶液A)或與對象(溶液B)。

數組優於對象的優點是對子對象的直接迭代。對於一個對象,你需要先獲得鍵值,然後再進行迭代。

否則,如果你知道一個孩子,那麼通過密鑰的訪問速度更快。將新節點插入樹中也是如此。

對於兒童陣列,您需要一個功能getChild來測試孩子是否在場。

需要注意的是,提供的數據不會保持標識符的唯一性。與陣列

溶液A爲兒童:

function Node(id) { 
 
    this.id = id; 
 
    this.children = []; // array 
 
} 
 

 
Node.prototype.getChild = function (id) { 
 
    var node; 
 
    this.children.some(function (n) { 
 
     if (n.id === id) { 
 
      node = n; 
 
      return true; 
 
     } 
 
    }); 
 
    return node; 
 
}; 
 

 
var path = ['A-->B-->C-->D-->E', 'A-->B-->C-->D-->F', 'A-->F-->C-->D-->E'], 
 
    tree = new Node('root'); 
 

 
path.forEach(function (a) { 
 
    var parts = a.split('-->'); 
 
    parts.reduce(function (r, b) { 
 
     var node = r.getChild(b); 
 
     if (!node) { 
 
      node = new Node(b); 
 
      r.children.push(node); 
 
     } 
 
     return node; 
 
    }, tree); 
 
}); 
 

 
document.getElementById('out').innerHTML = JSON.stringify(tree, 0, 4);
<pre id="out"></pre>

與對象B液爲兒童:

function Node(id) { 
 
    this.id = id; 
 
    this.children = {}; // object 
 
} 
 

 
var path = ['A-->B-->C-->D-->E', 'A-->B-->C-->D-->F', 'A-->F-->C-->D-->E'], 
 
    tree = new Node('root'); 
 

 
path.forEach(function (a) { 
 
    var parts = a.split('-->'); 
 
    parts.reduce(function (r, b) { 
 
     if (!r.children[b]) { 
 
      r.children[b] = new Node(b); 
 
     } 
 
     return r.children[b]; 
 
    }, tree); 
 
}); 
 

 
document.getElementById('out').innerHTML = JSON.stringify(tree, 0, 4);
<pre id="out"></pre>

兩個提議都使用Array#forEachArray#reduce迭代給定的字符串並將引用返回給實際的id。如果沒有找到id,則獲取節點的新實例並將其添加到數組或對象。該引用將返回給下一個ID檢查。

+0

我看到你對'console.log()'不滿意,並且開始對嵌套的thingys使用更酷的顯示方法。 (+)爲您的解決方案。 – Redu

+0

@Redu,是的,該地區是小到顯示更大的數據結構。 –