Reputation: 352
I have a json response and I want to simplify this json data with recursion and reduce. I write a function put i stuck at this point. I want to remove all data element and create a new object without data name.
My json data is like this
[
{
"city": {
"data": {
"id": 649442,
"country_id": 54,
"state_id": 682,
"city_name": "Prague",
"state_name": "Praha"
}
},
"country": {
"data": {
"id": 54,
"data": {
"country_name": "Czech Republic",
"short_country": "CZ",
"olympic_code": "CZE"
}
}
}
}
]
And my function is here:
function normalizeData(object) {
return Object.keys(object).reduce((finalObject, objectKey) => {
if (object[objectKey] && object[objectKey].data) {
finalObject[objectKey] = object[objectKey].data;
if (Array.isArray(finalObject[objectKey].data)) {
finalObject[objectKey] = object[objectKey].data.map(item => {
return normalizeData(item);
});
} else {
finalObject[objectKey] = normalizeData(object[objectKey].data);
}
} else {
finalObject[objectKey] = object[objectKey];
}
return finalObject;
}, {});
};
At the and I am still getting data object. So where am I making mistake. Or is there a better way to do this?
Upvotes: 2
Views: 4557
Reputation: 352
I found my mistake. I have an array on top of the object :) so I fixed the code like this.
export function normalizeData(object) {
return Object.keys(object).reduce((finalObject, objectKey) => {
if (object[objectKey] && object[objectKey].data) {
finalObject[objectKey] = object[objectKey].data;
if (Array.isArray(finalObject[objectKey].data)) {
finalObject[objectKey] = object[objectKey].data.map(item => {
return normalizeData(item);
});
} else {
finalObject[objectKey] = normalizeData(object[objectKey].data);
}
} else {
finalObject[objectKey] = object[objectKey];
}
return finalObject;
}, {});
}
export function normalizeArray(array) {
return array.map(object => {
return normalizeData(object);
})
}
Upvotes: 0
Reputation: 4968
This is a solution without reduce()
, that checks if the object properties are not inherited (hasOwnProperty()
), and does a recursion for each property that is an object itself. It the property key is data
, then all the values get copied to the parent object and the data
key gets deleted from the object afterwards. This is where it gets tricky because the data
object can have a data
property itself, so this has to be checked and a double recursion needs to be applied.
var jsonStr = `{
"city": {
"data": {
"id": 649442,
"country_id": 54,
"state_id": 682,
"city_name": "Prague",
"state_name": "Praha"
}
},
"country": {
"data": {
"id": 54,
"data": {
"country_name": "Czech Republic",
"short_country": "CZ",
"olympic_code": "CZE"
}
}
}
}`;
var jo = JSON.parse(jsonStr);
function normalize(obj) {
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
if (typeof obj[key] === 'object') {
if (key === 'data') {
// check if data object also has a data property
if (obj[key].hasOwnProperty('data')) {
// double recursion
normalize(obj[key]);
normalize(obj);
}
else {
// copy all values to the parent
// (only if they don't exist in the parent yet)
for (var subKey in obj[key]) {
if (obj[key].hasOwnProperty(subKey)
&& !obj.hasOwnProperty(subKey)) {
obj[subKey] = obj[key][subKey];
}
}
// remove the data key
delete obj[key];
}
}
else {
// recursion
normalize(obj[key]);
}
}
}
}
}
normalize(jo);
console.log(jo);
you can use a deep extend to create a copy of the object first and return that one, if you don't want the function to modify the input.
Upvotes: 2