I need to parse some data got from BE from one format to another to can inject it into a table component. The format received is:
{
"displayName": "Income",
"baseVersionSum": null,
"comparisonVersionSum": null,
"variance": null,
"variancePercent": null,
"children": [
{
"displayName": "4000 Revenue",
"baseVersionSum": null,
"comparisonVersionSum": null,
"variance": null,
"variancePercent": null,
"children": [
{
"displayName": "4100 Product 1 Revenue",
"baseVersionSum": -1000000,
"comparisonVersionSum": 4300000,
"variance": -5300000,
"variancePercent": -123,
"children": []
}
]
}
]
}
and I need the following format:
{
"key": "Income",
"data": {
"displayName": "Income",
"baseVersionSum": null,
"comparisonVersionSum": null,
"variance": null,
"variancePercent": null
},
"children": [
{
"key": "4000 Revenue",
"data": {
"displayName": "4000 Revenue",
"baseVersionSum": null,
"comparisonVersionSum": null,
"variance": null,
"variancePercent": null
},
"children": [
{
"key": "4100 Product 1 Revenue",
"data": {
"displayName": "4100 Product 1 Revenue",
"baseVersionSum": -1000000,
"comparisonVersionSum": 4300000,
"variance": -5300000,
"variancePercent": -123
},
"children": []
}
]
}
]
}
Each parent can have more children or no children. I tried to do something with reduce, but no result. This is what I've tried:
const prepareTableValue = (data: any): any => {
const res = data.reduce((result: any, node) => {
if (node.children) {
result.push({
key: node.displayName,
data: {
displayName: node.displayName,
baseBersionSum: node.baseVersionSum,
comparisonVersionSum: node.comparisonVersionSum,
variance: node.variance,
variancePercent: node.variancePercent,
},
children: node.children,
});
prepareTableValue(node.children);
}
return result;
}, []);
return res;
};
Thanks in advance!
CodePudding user response:
Nice challenge ! Here is a solution with a recursive function that creates a new object and adds to it recursively by going through each child of the initial object and calling itself for that child and the child in that position in the new object:
const objToFormat = {
"displayName": "Income",
"baseVersionSum": null,
"comparisonVersionSum": null,
"variance": null,
"variancePercent": null,
"children": [
{
"displayName": "4000 Revenue",
"baseVersionSum": null,
"comparisonVersionSum": null,
"variance": null,
"variancePercent": null,
"children": [
{
"displayName": "4100 Product 1 Revenue",
"baseVersionSum": -1000000,
"comparisonVersionSum": 4300000,
"variance": -5300000,
"variancePercent": -123,
"children": []
}
]
}
]
};
const formatData = (objToFormat, formattedObj = {}) => {
const { displayName, children, ...data } = objToFormat;
formattedObj.key = displayName;
formattedObj.data = { displayName, ...data };
formattedObj.children = [];
children.forEach((child, i) => {
formattedObj.children[i] = {};
formatData(child, formattedObj.children[i]);
})
return formattedObj;
}
console.log(formatData(objToFormat))
CodePudding user response:
A recursive parse should work.
function parseData(items: any[]) {
const parsed = items.map((item) => {
const clone = Object.create(item);
clone.key = clone.displayName;
clone.data = {
displayName: clone.displayName,
baseBersionSum: clone.baseVersionSum,
comparisonVersionSum: clone.comparisonVersionSum,
variance: clone.variance,
variancePercent: clone.variancePercent,
};
clone.children = parseData(clone.children);
return clone;
});
return parsed;
}