So I was trying this for hours now, needed some help.
I have a string with dots which I need to convert into a nested JSON Objects.
data=
"REPM.Action.Portfolio.budget.repairDetails.excelExport" "."
"REPM.Action.Portfolio.bsc.list.keyCalculate" "."
"REPM.Action.Portfolio.bsc.Overview.keyLoad" "."
"REPM.Action.Portfolio.budget.versionSelection.createVersion" "."
"REPM.Action.Portfolio.dcf.dcfCompare.keyExportWorksheet" "."
"REPM.Action.Portfolio.dcf.keyRateCompare.keyExportWorksheet" "."
"REPM.Action.Portfolio.dcf.keyScenario.keyClone" "."
"REPM.Action.Portfolio.dcf.keyScenario.keyDelete" "."
"REPM.Action.Portfolio.dcf.keyScenario.keyNewCalculation" "."
"REPM.Action.Portfolio.dcf.keyScenario.keyNewMandate" "."
"REPM.Action.Portfolio.dcf.keySelection.keyDefinitive";
And the output is expected to look something like this
{
"REPM": {
"Action": {
"Portfolio": {
"budget": {
"repairDetails": {
"excelExport": null
},
"versionSelection": {
"createVersion": null
}
},
"bsc": {
"list": {
"keyCalculate": null
},
"Overview": {
"keyLoad": null
}
},
"dcf": {
"dcfCompare": {
"keyExportWorksheet": null
},
"keyRateCompare": {
"keyExportWorksheet": null
},
"keyScenario": {
"keyClone": null,
"keyDelete": null,
"keyNewCalculation": null,
"keyNewMandate": null,
},
"keySelection": {
"keyDefinitive": null
}
}
}
}
}
}
Currently I have tried...
var tempObject = {};
var value = this.receivedString.split('.')
console.log(value.length)
var curr = tempObject;
for (var i = 0; i < value.length; i ) {
var next = {}
curr[value[i]] = next;
curr = next;
}
}
This is giving me a flat object with basically each object inside another, with repeated properties.
{
"REPM":{
"Action":{
"Portfolio":{
"budget":{
"repairDetails"{
"excelExport":{
"REPM":{
"Action":{
"Portfolio":{ //and so on...
}
}
}
}
}
}
}
}
}
}
would appreciate some help, thanks.
CodePudding user response:
Well, here it is, but this algorithm is a little advanced. It might take some time to wrap your head around. Let me know if my explanation doesn't make sense.
- You need to create an empty JavaScript object.
- Walk down the string, entry by entry.
- On new property names, you create a new object at your current position in the JavaScript object. This object becomes your new nesting 'level'.
- On recurring property names, you jump up to that level in your JavaScript object.
(Once you're done, you convert any empty objects to null
, which actually takes more lines of code.)
const data =
"REPM.Action.Portfolio.budget.repairDetails.excelExport" "."
"REPM.Action.Portfolio.bsc.list.keyCalculate" "."
"REPM.Action.Portfolio.bsc.Overview.keyLoad" "."
"REPM.Action.Portfolio.budget.versionSelection.createVersion" "."
"REPM.Action.Portfolio.dcf.dcfCompare.keyExportWorksheet" "."
"REPM.Action.Portfolio.dcf.keyRateCompare.keyExportWorksheet" "."
"REPM.Action.Portfolio.dcf.keyScenario.keyClone" "."
"REPM.Action.Portfolio.dcf.keyScenario.keyDelete" "."
"REPM.Action.Portfolio.dcf.keyScenario.keyNewCalculation" "."
"REPM.Action.Portfolio.dcf.keyScenario.keyNewMandate" "."
"REPM.Action.Portfolio.dcf.keySelection.keyDefinitive";
function recurrentDotSplit( data ) {
const keys = {};
let result = null, level = null;
const entries = data.split( '.' );
for( const entry of entries ) {
if( ! keys[ entry ] ) {
keys[ entry ] = {};
if( level ) level[ entry ] = keys[ entry ]
}
if( ! result ) result = { [ entry ]: keys[ entry ] };
level = keys[ entry ];
}
const ennulled = new Set();
function ennull( o ) {
if( ennulled.has( o ) ) return o;
ennulled.add( o );
const keys = Object.keys( o );
if( keys.length === 0 ) return null;
Object.keys( o ).forEach( key => o[ key ] = ennull( o[ key ] ) );
return o;
}
ennull( result );
return result;
}
var objectStructure = recurrentDotSplit( data );
console.log( objectStructure );