배열을 계층형(tree)으로 처리 및 노드찾기
1. 알고리즘
// 데이터 정의를 가능한 작게 만듭니다.
// 각 항목은 [name, parent_pos_in_array]입니다.
// note : 자식 노드 앞에 부모 노드가 있어야합니다.
var data = [
["UK", -1], //root..
["South-East", 0],
["South-West", 0],
["Berkshire", 1],
["Reading", 3]
//...etc...
];
// 제공된 flat arr을 트리로 변환하고 루트를 반환합니다.
// (부모 앞에 선언 된 자식이 없다고 가정)
function makeTree(arr){
//모든 자식 요소가 올바르게 설정된 배열
var treeArr = new Array(arr.length);
for(var i = 0, len = arr.length; i < len; i++){
var arrI = arr[i];
var newNode = treeArr[i] = {
name: arrI[0],
children: []
};
var parentI = arrI[1];
if(parentI > -1){ //i.e. not the root..
treeArr[parentI].children.push(newNode);
}
}
return treeArr[0]; //return the root..
}
var root = makeTree(data);
스피드체크
var data = [['root', -1]];
for(var i = 1; i < 100000; i++){
var parentI = Math.floor(Math.random()*(i-1));
data.push(['a_name', parentI]);
}
var start = new Date().getTime();
var tree = makeTree(data);
var end = new Date().getTime();
console.log('Took: ' + (end-start) + 'ms.');
배열에 100,000 개의 요소가 있으면 이전 데스크탑에서 200ms 미만의 시간이 소요됩니다. 어떤 종류의 성능이 받아 들여 지는지 확실하지 않습니다.
2. 알고리즘
var arry = [{ "Id": "1", "Name": "abc", "Parent": "", "attr": "abc" },
{ "Id": "2", "Name": "abc", "Parent": "1", "attr": "abc" },
{ "Id": "3", "Name": "abc", "Parent": "2", "attr": "abc" },
{ "Id": "4", "Name": "abc", "Parent": "2", "attr": "abc" }];
function convert(array){
var map = {};
for(var i = 0; i < array.length; i++){
var obj = array[i];
obj.children= [];
map[obj.Id] = obj;
var parent = obj.Parent || '-';
if(!map[parent]){
map[parent] = {
children: []
};
}
map[parent].children.push(obj);
}
return map['-'].children;
}
var getParent = function (rootNode, rootId) {
if (rootNode.Id == rootId)
return rootNode;
for (var i = 0; i < rootNode.children.length; i++) {
var child = rootNode.children[i];
if (child.Id == rootId) return child;
if (child.children.length > 0)
var childResult = getParent(child, rootId);
if (childResult != null) return childResult;
}
return null;
};
var r = convert(arry);
var x = getParent(r[0],1);
console.log('x--->',x);
console.log('array', r);
console.log('result', JSON.stringify(r))
//==================================================================
결과 : r 변수값
//==================================================================
array
[Object]
- 0: Object
- Id: "1"
- Name: "abc"
- Parent: ""
- attr: "abc"
- children: Array[1]
- 0: Object
- Id: "2"
- Name: "abc"
- Parent: "1"
- attr: "abc"
- children: Array[2]
- 0: Object
- Id: "3"
- Name: "abc"
- Parent: "2"
- attr: "abc"
- children: Array[0]
- __proto__: Object
- 1: Object
- Id: "4"
- Name: "abc"
- Parent: "2"
- attr: "abc"
- children: Array[
- 0: Object
- 0: Object
//==================================================================
결과 : x 변수값
//==================================================================
Object {Id: "3", Name: "abc", Parent: "2", attr: "abc", children: Array[0]}
- Id: "3"
- Name: "abc"
- Parent: "2"
- attr: "abc"
- children: Array[0]
//==================================================================
결과 : result 변수값
//==================================================================
result [{"Id":"1","Name":"abc","Parent":"","attr":"abc","children":[{"Id":"2","Name":"abc","Parent":"1","attr":"abc","children":[{"Id":"3","Name":"abc","Parent":"2","attr":"abc","children":[]},{"Id":"4","Name":"abc","Parent":"2","attr":"abc","children":[]}]}]}]
3. 알고리즘
var data = [
{ "name" : "ABC", "parent":"DEF", "relation": "ghi", "depth": 1 },
{ "name" : "DEF", "parent":"null", "relation": "null", "depth": 0 },
{ "name" : "new_name", "parent":"ABC", "relation": "rel", "depth": 2 },
{ "name" : "new_name2", "parent":"ABC", "relation": "foo", "depth": 2 },
{ "name" : "Foo", "parent":"DEF", "relation": "rel", "depth": 2 },
{ "name" : "Bar", "parent":"null", "relation": "rel", "depth": 2 }
];
// 생성
var dataMap = data.reduce(function(map, node) {
map[node.name] = node;
return map;
}, {});
// Tree형 배열 생성
var tree = [];
data.forEach(function(node) {
// 부모 배열에 추가
var parent = dataMap[node.parent];
if (parent) {
// 자식 배열이 없으면 만듭니다.
(parent.children || (parent.children = []))
// 자식 배열에 노드 추가
.push(node);
} else {
// 부모가 null 또는 없으면
tree.push(node);
}
});
// 콘솔로그로 확인
console.log( JSON.stringify(tree, null, ' ') );
//==================================================================
결과 : tree 변수값
//==================================================================
[ { "name": "DEF", "parent": "null", "relation": "null", "depth": 0, "children": [ { "name": "ABC", "parent": "DEF", "relation": "ghi", "depth": 1, "children": [ { "name": "new_name", "parent": "ABC", "relation": "rel", "depth": 2 }, { "name": "new_name2", "parent": "ABC", "relation": "foo", "depth": 2 } ] }, { "name": "Foo", "parent": "DEF", "relation": "rel", "depth": 2 } ] }, { "name": "Bar", "parent": "null", "relation": "rel", "depth": 2 } ]
4. 알고리즘
/*
입력값 :
Array (
[0] => Array
(
[id] => 1
[children] => Array
(
[0] => Array
(
[id] => 2
[children] => Array
(
[0] => Array
(
[id] => 3
)
[1] => Array
(
[id] => 4
)
)
)
[1] => Array
(
[id] => 5
)
)
)
)
*/
function handleNode(node, previousLeft, all) {
var indexed = {};
all.push(indexed);
indexed.id = node["id"];
indexed.left = previousLeft + 1;
var lastRight = indexed.left;
for (var x in node["children"]) {
lastRight = handleNode(node["children"][x], lastRight, all);
}
indexed.right = lastRight + 1;
return indexed.right;
}
var all = [];
handleNode(struct[0], 0, all);
console.log(all);