0

Given Below is my data in data array. What i am doing in code below is that from that given data i have to construct json in a special format which i also gave below.

//code start here
 var hierarchy={};
 hierarchy.name="Hierarchy";
 hierarchy.children=[{"name":"","children":[{"name":"","children":[]}]}];
 var countryindex;
 var flagExist=false;
 var data = [
 {country :"America", city:"Kansas", employe:'Jacob'},
 {country :"Pakistan", city:"Lahore", employe:'tahir'},
 {country :"Pakistan", city:"Islamabad", employe:'fakhar'} ,
 {country :"Pakistan", city:"Lahore", employe:'bilal'},
 {country :"India", city:"d", employe:'ali'} ,
 {country :"Pakistan", city:"Karachi", employe:'eden'},
 {country :"America", city:"Kansas", employe:'Jeen'} ,
 {country :"India", city:"Banglore", employe:'PP'} ,
 {country :"India", city:"Banglore", employe:'JJ'} ,
 ];
 for(var i=0;i<data.length;i++)
 {
 for(var j=0;j<hierarchy.children.length;j++)
 {
 //for checking country match
 if(hierarchy.children[j].name==data[i].country)
 {
 countryindex=j;
 flagExist=true;
 break;
 }
 }
 if(flagExist)//country match now no need to add new country just add city in it
 {
 var cityindex;
 var cityflag=false;
 //hierarchy.children[countryindex].children.push({"name":data[i].city,"children":[]})
 //if(hierarchy.children[index].children!=undefined)
 for(var k=0;k< hierarchy.children[countryindex].children.length;k++)
 {
 //for checking city match
 if(hierarchy.children[countryindex].children[k].name==data[i].city)
 {
 // hierarchy.children[countryindex].children[k].children.push({"name":data[i].employe})
 cityflag=true;
 cityindex=k;
 break;
 }
 }
 if(cityflag)//city match now add just empolye at that city index
 {
 hierarchy.children[countryindex].children[cityindex].children.push({"name":data[i].employe});
 cityflag=false;
 }
 else//no city match so add new with employe also as this is new city so its emplye will be 1st
 {
 hierarchy.children[countryindex].children.push({"name":data[i].city,children:[{"name":data[i].employe}]});
 //same as above
 //hierarchy.children[countryindex].children[length-1].children.push({"name":data[i].employe});
 }
 flagExist=false;
 }
 else{ //no country match adding new country //with city also as this is new city of new country
 console.log("sparta");
 hierarchy.children.push({"name":data[i].country,"children":[{"name":data[i].city,"children":[{"name":data[i].employe}]}]});
 // hierarchy.children.children.push({"name":data[i].city,"children":[]});
 }
 //console.log(hierarchy);
 }
 hierarchy.children.shift();
 var j=JSON.stringify(hierarchy);
//code ends here

//here is the json which i seccessfully formed from the code

{
"name":"Hierarchy",
"children":[
{
"name":"America",
"children":[
{
"name":"Kansas",
"children":[{"name":"Jacob"},{"name":"Jeen"}]}]},
{
"name":"Pakistan",
"children":[
{
"name":"Lahore",
"children":
[
{"name":"tahir"},{"name":"bilal"}]},
{
"name":"Islamabad",
"children":[{"name":"fakhar"}]},
{
"name":"Karachi",
"children":[{"name":"eden"}]}]},
{
"name":"India",
"children":
[
{
"name":"d",
"children":
[
{"name":"ali"}]},
{
"name":"Banglore",
"children":[{"name":"PP"},{"name":"JJ"}]}]}]}

Now the orignal problem is that currently i am solving this problem for data of array of three keys and i have to go for 3 nested loops now i want to optimize this solution so that if data array of object has more than 3 key say 5 {country :"America", state:"NewYork",city:"newYOrk",street:"elm", employe:'Jacob'}, or more than my solution will not work and i cannot decide before how many keys will come so i thought recursion may suit best here. But i am horrible in writing recurrsion and the case is also complex. Can some awesome programmer help me writing recurrsion or suggest some other solution.

asked Nov 6, 2013 at 11:34
1
  • I would suggest trying your hand at a recursive solution, then posting where you have problems with it. Commented Nov 6, 2013 at 12:40

1 Answer 1

2

I made a functions that can help you, is recursive and support any length levels, but the code is a bit long

 var data = [
 {country :"America", city:"Kansas", employe:'Jacob'},
 {country :"Pakistan", city:"Lahore", employe:'tahir'},
 {country :"Pakistan", city:"Islamabad", employe:'fakhar'} ,
 {country :"Pakistan", city:"Lahore", employe:'bilal'},
 {country :"India", city:"d", employe:'ali'} ,
 {country :"Pakistan", city:"Karachi", employe:'eden'},
 {country :"America", city:"Kansas", employe:'Jeen'} ,
 {country :"India", city:"Banglore", employe:'PP'} ,
 {country :"India", city:"Banglore", employe:'JJ'} ,
 ];
function groupByLevel( source, levels, config ){
 config = ( typeof config == "object" && config ) || {};
 var internalConfig = {
 keyName: config.keyName || "name",
 collectionName: config.collectionName || "children"
 };
 var hierarchy = {};
 hierarchy[internalConfig.keyName] = "Hierarchy";
 hierarchy[internalConfig.collectionName] = source;
 var sourceArray = [hierarchy];
 for(var i = 0; i < levels.length; i++){
 var newSourceArray = [];
 for(var j = 0; j < sourceArray.length; j++){
 var oldArray = sourceArray[j][internalConfig.collectionName];
 var newArray = groupBy(oldArray, levels[i], internalConfig); 
 sourceArray[j][internalConfig.collectionName] = newArray;
 for(var l = 0; l < newArray.length; l++){
 newSourceArray.push(newArray[l]);
 }
 }
 sourceArray = newSourceArray;
 }
 return hierarchy;
}
function duplicate(obj){
 var newObj = {};
 for(var i in obj) newObj[i] = obj[i];
 return newObj;
}
function objlength(obj){
 var length = 0;
 for(var i in obj) length++;
 return length
}
function groupBy(array, key, config){
 var group = {};
 for(var i = 0; i < array.length; i++){
 var item = array[i];
 var currentKey = item[key]; 
 if( ! group[currentKey] ) group[currentKey] = [];
 var clone = duplicate(item);
 delete clone[key]; 
 if( objlength(clone) ) group[currentKey].push( clone );
 }
 var returnGroup = [];
 for(var i in group){
 var groupItem = {};
 groupItem[config.keyName] = i;
 if( group[i].length ) groupItem[config.collectionName] = group[i];
 returnGroup.push( groupItem );
 }
 return returnGroup;
}
var result = groupByLevel(data, ["country", "city", "employe"] );
var yourJson = JSON.stringify(result);

the functions groupByLevel, groupBy, duplicate and objLength will to process your groupping.

in this link http://jsfiddle.net/Castrolol/2TkkW/ you can see a more level example with you data.

if you want, you can put on a single object to separe and turn reusable.

sorry for my bad english.

answered Nov 6, 2013 at 12:50
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.