I'm trying to figure out a way to turn and object like this :
{ "test.subtest.pass" : "test passed", "test.subtest.fail" : "test failed" }
into JSON like this:
{ "test": { "subtest": { "pass": "test passed", "fail": "test failed" }}}
sometimes there may be duplicate keys, as above perhaps there would be another entry like "test.subtest.pass.mark"
I have tried using the following method and it works but it's incredibly ugly:
convertToJSONFormat() {
const objectToTranslate = require('<linkToFile>');
const resultMap = this.objectMap(objectToTranslate, (item: string) => item.split('.'));
let newMap:any = {};
for (const [key,value] of Object.entries(resultMap)) {
let previousValue = null;
// @ts-ignore
for (const item of value) {
// @ts-ignore
if (value.length === 1) {
if(!newMap.hasOwnProperty(item)) {
newMap[item] = key
} // @ts-ignore
} else if (item === value[value.length - 1]) {
if(typeof previousValue[item] === 'string' ) {
const newKey = previousValue[item].toLowerCase().replace(/\s/g, '');;
const newValue = previousValue[item];
previousValue[item] = {};
previousValue[item][newKey] = newValue;
previousValue[item][item] = key;
} else {
previousValue[item] = key;
}
} else if (previousValue === null) {
if (!newMap.hasOwnProperty(item)) {
newMap[item] = {};
}
previousValue = newMap[item];
} else {
if (!previousValue.hasOwnProperty(item)) {
previousValue[item] = {}
previousValue = previousValue[item];
} else if (typeof previousValue[item] === 'string') {
const newValue = previousValue[item];
previousValue[item] = {};
previousValue[item][item] = newValue;
} else {
previousValue = previousValue[item];
}
}
}
}
return newMap;
}
CodePudding user response:
We can utilize recursion to make the code a little less verbose:
function convertToJSONFormat(objectToTranslate) {
// create object after mapping
const result = {};
// iterate each key-value pair on the object to be translated
Object
.entries(objectToTranslate)
.forEach(([path, value]) => {
// utilize a recursive function to write the value into the object
addArrayPathToObject(result, path.split("."), value);
});
return result;
}
function addArrayPathToObject(root, parts, value) {
const p = parts.shift();
// base-case: We attach the value if we reach the last path fragment
if (parts.length == 0) {
root[p] = value
return;
}
// general case: check if root[p] exists, otherwise create it and set as new root.
if(!root[p]) root[p] = {};
addArrayPathToObject(root[p], parts, value)
}
This function utilizes the fact that objects are pass-by-reference to recursively traverse through the object starting at its root until setting the desired value.
You can add error-handling and other such concerns as necessary for your use.
CodePudding user response:
@Meggan Naude, toJson function copies json object to reference obj for provided keys and value.
const p = { "test.subtest.pass" : "test passed", "test.subtest.fail" : "test failed" };
const result = {} ;
const toJson = (obj, keys, value) => {
if (keys?.length === 1) {
obj[keys[0]] = value;
return obj
} else {
const k = keys.splice(0, 1)
if (k in obj) {
toJson(obj[k], keys, value)
} else {
obj[k] = {};
toJson(obj[k], keys, value)
}
return obj
}
}
Object.keys(p).forEach(key => toJson(result, key.split('.'), p[key]))
console.log(result);