如何将平面javascript数组转换为嵌套图形结构?

时间:2011-06-09 22:36:28

标签: javascript json object translate

我将如何转换这个扁平的json结构:

[
    ["a","b","c"],
    ["a","b","d"],
    ["c","b","e"],
    ["c","b","f"]
]

使用javascript进入下面的图形结构?

{"uri": "a", "subItems": [
    {"uri": "b", "subItems": [
        {"uri": "c", "subItems": [
            {"uri": "b", "subItems": [
                {"uri": "e"},
                {"uri": "f"}
            ]}
        ]},
        {"uri": "d"}
    ]}
]}

2 个答案:

答案 0 :(得分:1)

我认为这应该让你真正关闭。它将整个JSON结果包装在一个数组中,这是为了简化getNode函数,但您可以轻松地获取数组的[0]索引。我开始试图遵循JSLint(因此i = i + 1而不是i ++),但我放弃了一半,所以代码可以清理一下。 ;)

http://jsfiddle.net/Zcyca/

var i, j, k, arr = 
[
    ["a","b","c"],
    ["a","b","d"],
    ["c","b","e"],
    ["c","b","f"]        
];

var results = [];
var last = results;

for(i = 0; i < arr.length; i = i + 1) {
    var subArr = arr[i];  
    var parentURI = subArr[0], middleURI = subArr[1], childURI = subArr[2]; 
    var parent, middle, child;

    // Find parent or create parent
    parent = getNode(results, parentURI);        
    if(parent === null) {
        results.push({"uri": parentURI, "subItems": []});
        parent = results[results.length-1];
    }        
    if(typeof parent["subItems"] === "undefined") {
        parent["subItems"] = [];
    }

    // Find middle or create middle
    middle = getNode(parent["subItems"], middleURI);
    if(middle === null) {
        parent["subItems"].push({"uri": middleURI, "subItems": []});
        middle = parent["subItems"][parent["subItems"].length-1];        
    }
    if(typeof middle["subItems"] === "undefined") {
        middle["subItems"] = [];
    }    

    // Find child or create child 
    child = getNode(middle["subItems"], childURI);
    if(child === null) {
        middle["subItems"].push({"uri": childURI});
        //child = middle["subItems"][middle["subItems"].length-1];            
    }
}

document.write(JSON.stringify(results));

function getNode(arr, uri) {
    var node = null;

    (function recurseArr(arr) {
        for(var i = 0; i < arr.length; i = i + 1) {
            var obj = arr[i];
            if(obj["uri"] === uri) {
                node = arr[i];
                break;   
            } else if(typeof obj["subItems"] !== "undefined") {  
                recurseArr(obj["subItems"]);
            }
        }
    })(arr);      

  return node;  
}

答案 1 :(得分:0)

似乎没有“简单”的方式。

我不知道如何处理需要查找其他匹配项的内容,例如,如果您要添加["b", "e", "b"]它应该去哪里?第二级或第四级的“b”?

http://jsfiddle.net/qVFCe/3/

var data = [
["a", "b", "c"],
["a", "b", "d"],
["c", "b", "e"],
["c", "b", "f"]
];

var group = null;

var baseStructure = {
    "uri": null,
    "subItems": []
};


function find(parent, uri) {
    for (var i = 0; parent.subItems && i < parent.subItems.length; i++) {
        if (parent.subItems[i].uri == uri) {
            return parent.subItems[i];
        }
    }
    return null;
}

function findRecursive(parent, uri) {
    var i, obj;
    //look in children
    for (i = 0; parent.subItems && i < parent.subItems.length; i++) {
        obj = find(parent.subItems[i], uri);
        if (obj !== null) {
            return obj;
        }
    }
    //look recursively in children
    for (i = 0; parent.subItems && i < parent.subItems.length; i++) {
        obj = findRecursive(parent.subItems[i], uri);
        if (obj !== null) {
            return obj;
        }
    }
    return null;
}


for (var i = 0; (group = data[i]); i++) {
    var current = baseStructure;
    for (var j = 0; j < group.length; j++) {
        var obj = find(current, group[j]);

        if (obj === null && j === 0) {
            obj = findRecursive(current, group[j]);
        }

        if (obj === null) {
            //create a new one if not found
            obj = {
                uri: group[j]
            };
            if(current.subItems === undefined)
            {
                current.subItems = [];
            }
            current.subItems.push(obj);
        }
        current = obj;
    }
}