The object I must parse:
const object = {
"item1": "value",
"item2/0/subitem1": "value",
"item2/0/subitem2": "value",
"item2/1/subitem1": "value",
"item2/1/subitem2": "value",
"item3/0/subitem1/subsubitem1": "value",
"item3/1/subitem1/subsubitem1": "value",
"item4/0/subitem1/0/subsubitem1": "value",
"item4/0/subitem1/1/subsubitem1": "value",
}
I would like to parse it into a nested object that looks like this:
const parsedObject = {
item1: value,
item2: [
{
subitem1: value,
subitem2: value,
},
{
subitem1: value,
subitem2: value,
}
],
item3: [
{
subtiem1: {
subsubitem1: value,
}
},
{
subtiem1: {
subsubitem1: value,
}
},
],
item4: [
{
subitem1: [
{
subsubitem1: value,
},
{
subsubitem1: value,
},
]
}
]
}
I have tried to write this function, but I'm stuck and do not know how to continue with it.
const object = {
"item1": "value",
"item2/0/subitem1": "value",
"item2/0/subitem2": "value",
"item2/1/subitem1": "value",
"item2/1/subitem2": "value",
"item3/0/subitem1/subsubitem1": "value",
"item3/1/subitem1/subsubitem1": "value",
"item4/0/subitem1/0/subsubitem1": "value",
"item4/0/subitem1/1/subsubitem1": "value",
}
const mainFunction = () => {
const specie = {};
const map = new Map();
Object.keys(object).forEach((key) => {
const keyTokens = key.split('/');
processKeyValues(specie, keyTokens, object[key], map);
});
console.log(specie);
}
const convertStringToBoolean = (str: string): string | boolean => {
return str.toLowerCase() === 'true' ? true : str.toLowerCase() === 'false' ? false : str;
};
const processKeyValues = (specie: any, keyTokens: any[], value: string, map: Map < any, any > ): any => {
keyTokens.reduce((prev, curr, index, array) => {
if (index === array.length - 1) {
const valuePossibleNumber = parseInt(value); //transform number strings into numbers
if (!isNaN(valuePossibleNumber)) {
prev[curr] = valuePossibleNumber;
return;
}
prev[curr] = convertStringToBoolean(value); //boolean strings into booleans
return;
}
const currentKeyPossibleNumber = parseInt(curr);
const currentKeyIsNumber = !isNaN(currentKeyPossibleNumber);
const nextKeyPossibleNumber = parseInt(array[index + 1]);
const nextKeyIsNumber = !isNaN(nextKeyPossibleNumber);
if (currentKeyIsNumber) {
const hasMappedIndex = map.has(currentKeyPossibleNumber);
let mappedIndex = map.get(currentKeyPossibleNumber);
if (!hasMappedIndex) {
mappedIndex = map.size;
map.set(currentKeyPossibleNumber, mappedIndex);
}
const currentKeyAsIndexDoesNotExist = !prev[mappedIndex];
if (currentKeyAsIndexDoesNotExist) {
if (nextKeyIsNumber) {
prev.push([]);
} else {
prev.push({});
}
}
return prev[mappedIndex];
}
const currentKeyDoesNotExist = !prev[curr];
if (currentKeyDoesNotExist) {
if (nextKeyIsNumber) {
prev[curr] = [];
map.clear();
} else {
prev[curr] = {};
}
}
return prev[curr];
}, specie);
};
The reason I use a map for the array indexes is that it may be that I do not receive those indexes necessarily in order like 0,1,2 etc., but also like 0,1,10,101 etc. and I access that index in the array I am creating because it is not that large.
Seeing that I am receiving these objects from an endpoint I cannot modify, it would be ideal if I could find a way to generalize the code to cover situations when I could get multiple nested arrays ans objects so I thought a recursive function would be best suited, but I cannot figure out how, thus I would be thankful if you could help me out.