배열을 계층형(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]

  1. 0: Object
    1. Id: "1"
    2. Name: "abc"
    3. Parent: ""
    4. attr: "abc"
    5. children: Array[1]
      1. 0: Object
        1. Id: "2"
        2. Name: "abc"
        3. Parent: "1"
        4. attr: "abc"
        5. children: Array[2]
          1. 0: Object
            1. Id: "3"
            2. Name: "abc"
            3. Parent: "2"
            4. attr: "abc"
            5. children: Array[0]
            6. __proto__: Object
          2. 1: Object
            1. Id: "4"
            2. Name: "abc"
            3. Parent: "2"
            4. attr: "abc"
            5. children: Array[

 

//==================================================================

결과 : x 변수값

//==================================================================

 

Object {Id: "3", Name: "abc", Parent: "2", attr: "abc", children: Array[0]}

  1. Id: "3"
  2. Name: "abc"
  3. Parent: "2"
  4. attr: "abc"
  5. 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);
//==================================================================
결과 : tree 변수값
//==================================================================
Array (
        [0] => Array
            (
                [id] => 1
                [left] => 1
                [right] => 10
            )
        [1] => Array
            (
                [id] => 2
                [left] => 2
                [right] => 7
            )
        [2] => Array
            (
                [id] => 3
                [left] => 3
                [right] => 4
            )
        [3] => Array
            (
                [id] => 4
                [left] => 5
                [right] => 6
            )
        [4] => Array
            (
                [id] => 5
                [left] => 8
                [right] => 9
            )
    )