Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How can I reduce an array of objects based on prop name?

I’m trying to turn:

  Array(19) [
{ category: 'Entertainment', 'Hang with Friends': 100 }, 
{ category: 'Entertainment', Chill: 30 }, 
{ category: 'Health', Yoga: 40 },
{ category: 'Health', Birthday: 200 }, 
   ]

into:

  Array(19) [
{ category: 'Entertainment', 'Hang with Friends': 100, Chill: 30 }, 
{ category: 'Health', Yoga: 40, Birthday: 200 },
   ]

I attempted to do it using the logic from my last question but that one was reduced based on a prop that was a number, so I could index it. Here, I’m trying to do it based off of the category prop which is a string and can’t be used to index.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I tried the following, but it doesn’t work at all:

  const reducedData = Object.values(newData).reduce(
    (index, { id, category, subCategory, price }) => {
      Object.assign((index[category] ??= category), {
        [subCategory]: price,
      });
      return index;
    },
    {}
  );

I want to be able to loop through the other objects in the array to find the obj with the correct category prop but I’m not sure how to do that.

Any help would be great!

Also, I’ve changed the format to the following because it was mentioned that it’s easier to work with. How would you the same to the following?

  Array(19) [
{ category: 'Entertainment', subCategory: 'Hang with Friends', price: 100 }, 
{ category: 'Entertainment', subCategory: 'Chill', price: 30 }, 
{ category: 'Health', subCategory: 'Yoga', price: 40 },
{ category: 'Health', subCategory: 'Birthday', price: 200 }, 
   ]

>Solution :

You can use Array#reduce with an object that stores the merged object using the category as the key.

const arr=[{category:"Entertainment","Hang with Friends":100},{category:"Entertainment",Chill:30},{category:"Health",Yoga:40},{category:"Health",Birthday:200},];
const res = Object.values(arr.reduce((acc, curr) =>
  (Object.assign(acc[curr.category] ??= {}, curr), acc), {}));
console.log(res);

You can use a type assertion for the accumulator in TypeScript:

const res = Object.values(arr.reduce((acc, curr) =>
 (Object.assign(acc[curr.category] ??= {}, curr), acc), {} as Record<string, unknown>));

Or you can set the generic type parameter for reduce:

arr.reduce<Record<string, unknown>>(...)
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading