I need to transform from one schema to another. Is there any way of achieving this without doing a for loop?
Original data
[
{
"browser": "Chrome",
"count": 73,
"verdict": "detected"
},
{
"browser": "Opera",
"count": 3,
"verdict": "detected"
},
{
"browser": "Chrome",
"count": 3,
"verdict": "blocked"
},
{
"browser": "Edge",
"count": 1,
"verdict": "detected"
}
]
Transformed data
[
{
"browser": "Chrome",
"detected":73,
"blocked":3
},
{
"browser": "Opera",
"detected": 3,
"blocked": 0
},
{
"browser": "Edge",
"detected": 1,
"blocked": 0
}
]
CodePudding user response:
Group them by the browser as a unique key, then the result is as easy as getting the values in the object.
const data=[{"browser":"Chrome","count":73,"verdict":"detected"},{"browser":"Opera","count":3,"verdict":"detected"},{"browser":"Chrome","count":3,"verdict":"blocked"},{"browser":"Edge","count":1,"verdict":"detected"}];
const grouped = data.reduce((o, { browser, count, verdict }) => {
// If it's not in the map yet, add it as an empty entry
if (!(browser in o)) o[browser] = { browser, detected: 0, blocked: 0 };
// By now, it must be in the map, so it's as easy as adding the count to the verdict
o[browser][verdict] = count;
// Return modified map for the next iteration
return o;
}, {});
const result = Object.values(grouped); // Get the values of the map
console.log(result); // Done!
.as-console-wrapper { max-height: 100% !important; top: 0; }
See destructuring if you're wondering about what (o, { browser, count, verdict }) =>
is doing, and the in
operator for checking if a key exists in an object.
CodePudding user response:
I'd create a temporary map, so it can be accessed by its keys.
Then you can iterate the elements and update the temp map:
const initial = [{
"browser": "Chrome",
"count": 73,
"verdict": "detected"
},
{
"browser": "Opera",
"count": 3,
"verdict": "detected"
},
{
"browser": "Chrome",
"count": 3,
"verdict": "blocked"
},
{
"browser": "Edge",
"count": 1,
"verdict": "detected"
}
];
const defaultValues = {
detected: 0,
blocked: 0
};
const ans = initial.reduce((acc, element) => {
const {
browser,
verdict,
count
} = element;
acc[browser] = {
browser,
...(acc[browser] || defaultValues),
[verdict]: count,
};
return acc;
}, {});
console.log(Object.values(ans));