http://jsfiddle.net/eYgGK/
I stole this script from a different post:
function convertToHierarchy() {
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" }
];
var nodeObjects = createStructure(arry);
for (var i = nodeObjects.length - 1; i >= 0; i--) {
var currentNode = nodeObjects[i];
if (currentNode.value.Parent === "") {
continue;
}
var parent = getParent(currentNode, nodeObjects);
if (parent === null) {
continue;
}
parent.children.push(currentNode);
nodeObjects.splice(i, 1);
}
console.dir(nodeObjects);
return nodeObjects;
}
function createStructure(nodes) {
var objects = [];
for (var i = 0; i < nodes.length; i++) {
objects.push({
value: nodes[i],
children: []
});
}
return objects;
}
function getParent(child, nodes) {
var parent = null;
for (var i = 0; i < nodes.length; i++) {
if (nodes[i].value.Id === child.value.Parent) {
return nodes[i];
}
}
return parent;
}
This script produces:
[{
"value": {
"Id": "1",
"Name": "abc",
"Parent": "",
"attr": "abc"
},
"children": [{
"value": {
"Id": "2",
"Name": "abc",
"Parent": "1",
"attr": "abc"
},
"children": [{
"value": {
"Id": "4",
"Name": "abc",
"Parent": "2",
"attr": "abc"
},
"children": []
}, {
"value": {
"Id": "3",
"Name": "abc",
"Parent": "2",
"attr": "abc"
},
"children": []
}]
}]
}]
What I'm looking for is:
[{
"Id": "1",
"Name": "abc",
"Parent": "",
"attr": "abc",
"children": [{
"Id": "2",
"Name": "abc",
"Parent": "1",
"attr": "abc",
"children": [{
"Id": "4",
"Name": "abc",
"Parent": "2",
"attr": "abc"
}, {
"Id": "3",
"Name": "abc",
"Parent": "2",
"attr": "abc"
}]
}]
}]
I need to get rid of "value" wrapper primarily, and the empty child node secondarily. I know I can write a clean up script, but that would be less than best practice. Would be great if someone knows how to fix, or suggest a different script!
Thanks
JSON is an ideal format for larger data that have a hierarchical structured relationship. The structure of a JSON object is as follows: The data are in name/value pairs. Data objects are separated by commas.
Yes, an array is legal as top-level JSON-text.
Rules for JSON Syntax Data should be in name/value pairs. Data should be separated by commas. Curly braces should hold objects. Square brackets hold arrays.
Try something like
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.items= [];
map[obj.Id] = obj;
var parent = obj.Parent || '-';
if(!map[parent]){
map[parent] = {
items: []
};
}
map[parent].items.push(obj);
}
return map['-'].items;
}
var r = convert(arry)
Demo: Fiddle
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" : []
}]
}]
}]
@Arun P Johny's answer is good, but it has a problem, when the array is not sorted, it will flush sub-trees. I updated it as this.
var arry = [
{ "Id": "5", "Name": "abc", "Parent": "3", "attr": "abc" },
{ "Id": "2", "Name": "abc", "Parent": "1", "attr": "abc" },
{ "Id": "4", "Name": "abc", "Parent": "2", "attr": "abc" },
{ "Id": "3", "Name": "abc", "Parent": "2", "attr": "abc" },
{ "Id": "1", "Name": "abc", "Parent": "", "attr": "abc" }
];
function convert(array){
var map = {}
for(var i = 0; i < array.length; i++){
var obj = array[i]
if(!(obj.Id in map)){
map[obj.Id] = obj
map[obj.Id].children = []
}
if(typeof map[obj.Id].Name == 'undefined'){
map[obj.Id].Id = obj.Id
map[obj.Id].Name = obj.Name
map[obj.Id].attr = obj.attr
map[obj.Id].Parent= obj.Parent
}
var parent = obj.Parent || '-';
if(!(parent in map)){
map[parent] = {}
map[parent].children = []
}
map[parent].children.push(map[obj.Id])
}
return map['-']
}
console.log(JSON.stringify(convert(arry)))
The result is as this:
{
"children": [
{
"children": [
{
"Id": "2",
"Name": "abc",
"Parent": "1",
"attr": "abc",
"children": [
{
"Id": "4",
"Name": "abc",
"Parent": "2",
"attr": "abc",
"children": []
},
{
"children": [
{
"Id": "5",
"Name": "abc",
"Parent": "3",
"attr": "abc",
"children": []
}
],
"Id": "3",
"Name": "abc",
"attr": "abc",
"Parent": "2"
}
]
}
],
"Id": "1",
"Name": "abc",
"attr": "abc",
"Parent": ""
}
]
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With