我正在尝试从列表中创建树。我的数据就像;
A-->B-->C-->D-->E..
A-->B-->C-->D-->F..
A-->F-->C-->D-->E..
.
.
.
我在数组中有所有可能的数据路径。我希望像
一样显示它 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);
});
};
答案 0 :(得分:3)
基本上,您可以为子项使用至少两种不同的结构来构建树,一种使用数组(解决方案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#forEach
和Array#reduce
来迭代给定的字符串,并将引用返回给实际的id。如果未找到id,则会获取新的节点实例并将其添加到数组或对象中。将返回引用以进行下一次ID检查。
答案 1 :(得分: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));