Reputation: 61
I want to reduce the array with only the subject being present in the new object.
array = [{
subject: "maths",
credits: 3
},
{
subject: "chemistry",
credits: 2,
lab: {
lab: "chemistry_lab",
lab_credits: 1,
},
}
]
the new object is reformatted and its values are assigned as strings. What's the best way to achieve this
const subject = {
maths: "",
chemistry: "",
chemistry_lab: "",
};
Here's how I tried this but it returns an array of objects, but I want this to be a single object as above
const sub = array.map((op) => {
const container = {};
container[op.subject] = "";
return container;
});
Upvotes: 0
Views: 112
Reputation: 347
let array = [{
subject: "maths",
credits: 3
},
{
subject: "chemistry",
credits: 2,
lab: {
lab: "chemistry_lab",
lab_credits: 1,
},
}
]
let subject = {}
array.forEach(el => {
subject[el.subject] = ""
if (el.lab) {
subject[el.lab.lab] = ""
}
})
console.log(subject)
// output
// { maths: "", chemistry: "", chemistry_lab: "" }
Upvotes: 1
Reputation: 646
var array = [
{
subject: "maths",
credits: 3
},
{
subject: "chemistry",
credits: 2,
lab : {
lab: "chemistry_lab",
lab_credits: 1,
},
}
];
var p = array.reduce((acc,i)=>{
acc[i.subject]= '';
if(i.lab){
acc[i.lab.lab]=''
}
return acc;
},{})
console.log(p)
You can also use JavaScript reduce
to achieve the same.
Here's snippet you can try :
var p = array.reduce((acc,i)=>{
acc[i.subject]= '';
if(i.lab){
acc[i.lab.lab]=''
}
return acc;
},{})
console.log(p)
Upvotes: 0
Reputation: 50664
Your map method is the right idea, however, it doesn't map the lab
objects. You could go for an approach that uses .flatMap()
to build an array of [key, value]
pairs from each object in your array. By flat-mapping, you can take each subject and lab (if it exists) and "convert" the object into two arrays of key values. You can then filter this mapped array to remove any [key, value]
pairs where the key
is a falsy value (ie: undefined), and then use Object.fromEntries()
on your array of [key, value]
pair arrays to build an object for you.
const array = [{ subject: "maths", credits: 3 }, { subject: "chemistry", credits: 2, lab: { lab: "chemistry_lab", lab_credits: 1, }, } ];
const res = Object.fromEntries(array.flatMap(obj => [
[obj.subject, ''], [obj.lab?.lab, '']
]).filter(([key]) => key));
console.log(res);
Another option could be to remove the .filter()
, and perform a check in your .flatMap()
function before adding the lab [key, value]
pair. This will help you avoid doing an additional iteration on your array:
const array = [{ subject: "maths", credits: 3 }, { subject: "chemistry", credits: 2, lab: { lab: "chemistry_lab", lab_credits: 1, }, } ];
const res = Object.fromEntries(array.flatMap(
obj => obj.lab?.lab
? [[obj.subject, ''], [obj.lab.lab, '']]
: [[obj.subject, '']]
));
console.log(res);
Lastly, a way using .reduce()
could look something like this. It builds up an object, adding the subject as a key using computed property names and will add the lab if it exists. It uses the spread syntax to spread the result of curr.lab?.lab && {[curr.lab.lab]: ''}
. When cur.lab.lab results in a truthy value, the object is spread and merged into the returned object literal:
const array = [{ subject: "maths", credits: 3 }, { subject: "chemistry", credits: 2, lab: { lab: "chemistry_lab", lab_credits: 1, }, } ];
const res = array.reduce((obj, curr) => ({
...obj,
[curr.subject]: '',
...(curr.lab?.lab && {[curr.lab.lab]: ''})
}), {});
console.log(res);
Upvotes: 1