I need to reduce the given object into some datastructure. This is my input object.
const receiver = {
USER1: {
module: ['a_critical', 'a_normal','b_normal']
},
USER2: {
module: ['a_critical', 'a_normal','b_critical']
},
USER3: {
module: ['a_critical']
}
};
const allModules = ['a_normal', 'a_critical', 'b_normal', 'b_critical'];
Desired output:
{
"a_critical": [
{
"user": [
"USER1", "USER2", "USER3"
]
}
],
"a_normal": [
{
"user": [
"USER1", "USER2"
]
}
],
"b_normal": [
{
"user": [
"USER1"
]
}
],
"b_critical": [
{
"user": [
"USER2"
]
}
]
}
I have tried doing but i was getting some problems. I am getting some duplicate properties which should be there. I can share the code on what i have tried.
const receiverObj = {};
let count = 0;
Object.keys(receiver).forEach((item) => {
receiver[item].module.forEach((module) => {
if(allModules.includes(module)) {
count = 1;
if(count) {
receiverObj[module] = [];
receiverObj[module].push({user: [item] });
}
receiverObj[module].push({user: item });
count = 0;
}
})
});
console.log(JSON.stringify(receiverObj, null, 2));
Actual result which i got:
{
"a_critical": [
{
"user": [
"USER3"
]
},
{
"user": "USER3"
}
],
"a_normal": [
{
"user": [
"USER2"
]
},
{
"user": "USER2"
}
],
"b_normal": [
{
"user": [
"USER1"
]
},
{
"user": "USER1"
}
],
"b_critical": [
{
"user": [
"USER2"
]
},
{
"user": "USER2"
}
]
}
Is there any optimal way of doing this ? can someone help ?
The array reduce in JavaScript is a predefined method used to reduce an array to a single value by passing a callback function on each element of the array. It accepts a function executed on all the items of the specified array in the left-to-right sequence. The returned single value is stored in the accumulator.
But did you know you can reduce them to objects as well? First, a quick overview of how reduce works. The reduce method receives two arguments: a function and an initial value. The function will run run for every value in the array, and receives two arguments as well: the accumulator, or acc , and the current value .
The reduce() method executes a user-supplied "reducer" callback function on each element of the array, in order, passing in the return value from the calculation on the preceding element. The final result of running the reducer across all elements of the array is a single value.
The reduce() method executes the function for each value of the array (non-empty array) from left to right. The reduce() method has the following syntax: let arr = [];arr. reduce(callback(acc, curVal, index, src), initVal);
Iterate over each module
in a reduce callback, creating a { user: [] }
object in the accumulator if it doesn't exist yet, and then push to that array:
const receiver = {
USER1: {
module: ['a_critical', 'a_normal','b_normal']
},
USER2: {
module: ['a_critical', 'a_normal','b_critical']
},
USER3: {
module: ['a_critical']
}
};
const output = Object.entries(receiver)
.reduce((a, [user, { module }]) => {
module.forEach((name) => {
if (!a[name]) {
a[name] = { user: [] };
}
a[name].user.push(user);
});
return a;
}, {});
console.log(output);
You could also create the accumulator object in advance, if you wanted, since you have allModules
, thereby avoiding conditionals inside the .reduce
:
const receiver = {
USER1: {
module: ['a_critical', 'a_normal','b_normal']
},
USER2: {
module: ['a_critical', 'a_normal','b_critical']
},
USER3: {
module: ['a_critical']
}
};
const allModules = ['a_normal', 'a_critical', 'b_normal', 'b_critical'];
const accum = Object.fromEntries(
allModules.map(
name => [name, { user: [] }]
)
);
const output = Object.entries(receiver)
.reduce((a, [user, { module }]) => {
module.forEach((name) => {
a[name].user.push(user);
});
return a;
}, accum);
console.log(output);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With