2011-06-09 85 views
1

如何转换这个扁平的json结构:如何将平面javascript数组转换为嵌套图形结构?

[ 
    ["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

你能解释一下你想要返回的结构?这个例子并不完全适合我。 – 2011-06-09 22:39:21

+0

您的数据是否保证没有循环引用?你到目前为止有什么? – YXD 2011-06-09 22:39:53

+0

因此,如果''c“'名称已经存在于结构中的任何位置,请使用它;否则创建一个新的顶级名称? – 2011-06-09 22:42:49

回答

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; 
} 
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; 
    } 
} 
相关问题