0

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;
});
6
  • I had tried this and did get the result. But the result I achieved is an array of objects like [{maths: "},{chemistry: "}]. But I want this to be just a single object Commented Apr 17, 2021 at 10:46
  • 1
    @MohammedRehan can you. sure your attempt by editing the questions and adding it in? Commented Apr 17, 2021 at 10:47
  • @NickParsons I have added my attempt Commented Apr 17, 2021 at 10:53
  • why is there "chemistry_lab" in this mapping? It's not a subject. What are the rules for this mapping? Commented Apr 17, 2021 at 10:54
  • @Thomas It wouldn't be there with mapping. For that I have added op.lab.lab which returns the "chemistry_lab". Commented Apr 17, 2021 at 10:59

3 Answers 3

1

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);

Sign up to request clarification or add additional context in comments.

Comments

1

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: "" }

Comments

0

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.