Rohìt Jíndal
Rohìt Jíndal

Reputation: 27232

Building a tree structure from a JSON object

There is an input JSON as per the below format.

var inputJSON = [{
    "TestScenario": "test1",
    "Application": "application1",
    "Market": "M1"
}, {
    "TestScenario": "test1",
    "Application": "application1",
    "Market": "M2"
}, {
    "TestScenario": "test1",
    "Application": "application1",
    "Market": "M3"
}, {
    "TestScenario": "test1",
    "Application": "application1",
    "Market": "M4"
}, {
    "TestScenario": "test2",
    "Application": "application2",
    "Market": "M5"
}, {
    "TestScenario": "test2",
    "Application": "application3",
    "Market": "M5"
}];

It should be structured as a tree in below format.

var outputJSON = [{
    "test1": {
        "application1": ["M1", "M2", "M3", "M4"]
    }
}, {
    "test2": {
        "application2": "M5",
        "application3": "M5"
    }
}];

What I have tried so far:

I am able to achieve the tree format with one kind of TestScenario but for multiple code breaks.

Working code for same kind of TestScenario :

var defaultArrays = [{
"TestScenario": "test1",
"Application": "application1",
"Market": "M1"
}, {
"TestScenario": "test1",
"Application": "application1",
"Market": "M2"
}, {
"TestScenario": "test1",
"Application": "application1",
"Market": "M3"
}, {
"TestScenario": "test1",
"Application": "application1",
"Market": "M4"
}];

var testScenario = [];

for (const data of defaultArrays) {
    if(testScenario.indexOf(data.TestScenario) === -1) {
        testScenario.push(data.TestScenario);
  }
}

var marketArray = [];
var shouldLookLikeThis = [];
var obj = {};
for (const b of defaultArrays) {
    for (const c of testScenario) {
        if (b.TestScenario === c) {
      obj[c] = {};
      obj[c][b.Application] = [];
      }
      if (shouldLookLikeThis.indexOf(obj) === -1) {
        shouldLookLikeThis.push(obj);
      }
    }
    
    for (const c of shouldLookLikeThis) {
      var arr1 = Object.keys(c);
      for (const d of arr1) {
        if (b.TestScenario === d) {
            var arr2 = Object.keys(c[d]);
          for (const e of arr2) {
            if(b.Application === e) {
                            marketArray.push(b.Market);
                c[d][e] = marketArray;
            }
          }
        }
      }
    }
  }
  
console.log('shouldLookLikeThis', shouldLookLikeThis);

Not working with multiple TestScenario :

var defaultArrays = [{
"TestScenario": "test1",
"Application": "application1",
"Market": "M1"
}, {
"TestScenario": "test1",
"Application": "application1",
"Market": "M2"
}, {
"TestScenario": "test1",
"Application": "application1",
"Market": "M3"
}, {
"TestScenario": "test1",
"Application": "application1",
"Market": "M4"
}, {
"TestScenario": "test2",
"Application": "application2",
"Market": "M5"
}, {
"TestScenario": "test2",
"Application": "application3",
"Market": "M5"
}];
var testScenario = [];

for (const data of defaultArrays) {
    if(testScenario.indexOf(data.TestScenario) === -1) {
        testScenario.push(data.TestScenario);
  }
}

var marketArray = [];
var shouldLookLikeThis = [];
var obj = {};
for (const b of defaultArrays) {
    for (const c of testScenario) {
        if (b.TestScenario === c) {
      obj[c] = {};
      obj[c][b.Application] = [];
      }
      if (shouldLookLikeThis.indexOf(obj) === -1) {
        shouldLookLikeThis.push(obj);
      }
    }
    
    for (const c of shouldLookLikeThis) {
      var arr1 = Object.keys(c);
      for (const d of arr1) {
        if (b.TestScenario === d) {
            var arr2 = Object.keys(c[d]);
          for (const e of arr2) {
            if(b.Application === e) {
                            marketArray.push(b.Market);
                c[d][e] = marketArray;
            }
          }
        }
      }
    }
  }
  
console.log('shouldLookLikeThis', shouldLookLikeThis);

Upvotes: 1

Views: 100

Answers (2)

kht
kht

Reputation: 590

I created an object of different test scenarios, iterated over the input to populate the test scenarios, and then converted the output back into an array per your formatting request.

var inputJSON = [{
    "TestScenario": "test1",
    "Application": "application1",
    "Market": "M1"
}, {
    "TestScenario": "test1",
    "Application": "application1",
    "Market": "M2"
}, {
    "TestScenario": "test1",
    "Application": "application1",
    "Market": "M3"
}, {
    "TestScenario": "test1",
    "Application": "application1",
    "Market": "M4"
}, {
    "TestScenario": "test2",
    "Application": "application2",
    "Market": "M5"
}, {
    "TestScenario": "test2",
    "Application": "application3",
    "Market": "M5"
}];

function convertJson(inp) {
    let out = {};
    
    inp.forEach(function(o) {
       if (!out[o.TestScenario]) {
         out[o.TestScenario] = {};
       }
       
       if (!out[o.TestScenario][o.Application.trim()]) {
         out[o.TestScenario][o.Application.trim()] = [];
       }
       
       out[o.TestScenario][o.Application.trim()].push(o.Market.trim());
       
   });
   
  let outArray = Object.keys(out).map(function(k) {
    let d = {};
    d[k] = out[k];
    
    return d;
  });
  
  return outArray;
}

console.log(convertJson(inputJSON));

Upvotes: 3

Shidersz
Shidersz

Reputation: 17190

One possible solution is to use Array.reduce() to first do the grouping procedure. After this, you could Array.map() the Object.entries() of the previous result to get your desired structure.

Example:

var inputJSON = [
  {"TestScenario": "test1", "Application": "application1", "Market": "M1"},
  {"TestScenario": "test1", "Application": "application1", "Market": "M2"},
  {"TestScenario": "test1", "Application": "application1", "Market": "M3"},
  {"TestScenario": "test1", "Application": "application1", "Market": "M4"},
  {"TestScenario": "test2", "Application": "application2", "Market": "M5"},
  {"TestScenario": "test2", "Application": "application3", "Market": "M5"}
];

let res = inputJSON.reduce((acc, {TestScenario, Application, Market}) =>
{
    acc[TestScenario] = acc[TestScenario] || {};
    acc[TestScenario][Application] = acc[TestScenario][Application] || [];
    acc[TestScenario][Application].push(Market);
    return acc;
}, {})

res = Object.entries(res).map(([key, val]) => ({[key]: val}));

console.log(res);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

Upvotes: 4

Related Questions