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

Map array of objects with matching records in Javascript

I have array of objects inside which I have items and attachments as separated.

Current Behaviour:

const data = {
   id: 1,
   name: 'Test',
   attachments: [
   {id: 1, itemId: -1, attachmentName: 'hello.jpg'},
   {id: 2, itemId: -1, attachmentName: 'world.jpg'},
   {id: 3, itemId: 2, attachmentName: 'image.jpg'}
   ],
   items: [
    {id: -1, itemName: 'Item One'},
    {id: 2, itemName: 'Item Two'},
   ]
}

console.log('data ', data);

Here to map attachments with items, we have itemId inside each attachment which will map with id of each item.

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

Expected Result:

 const data = {
   id: 1,
   name: 'Test',
   items: [
    { 
      id: -1, 
      itemName: 'Item One',  
      attachments: [
       {id: 1, itemId: -1, attachmentName: 'hello.jpg'},
       {id: 2, itemId: -1, attachmentName: 'world.jpg'}
     ]
    },
    {
     id: 2, 
     itemName: 'Item Two', 
     attachements: [
      {id: 3, itemId: 2, attachmentName: 'image.jpg'}
     ]
   },
  ]
}

Things I have tried,

const results = data.attachments.reduce((results, item) => {
    (results[item.id] = results[item.id] || []).push(item);
    return results;
}, {});

Tried grouping each attachment based on Id, but this doesn’t come along way.

Could someone kindly help to achieve the desired output?

Big thanks in advance.

>Solution :

You could create a Map keyed by itemId, with the item objects as corresponding values, where each object gets an attachments array that is initially empty.

Then iterate the data to populate those attachment arrays.

Finally get the objects from the Map to construct the final object:

const data = {id: 1,name: 'Test',attachments: [{id: 1, itemId: -1, attachmentName: 'hello.jpg'},{id: 2, itemId: -1, attachmentName: 'world.jpg'},{id: 3, itemId: 2, attachmentName: 'image.jpg'}],items: [{id: -1, itemName: 'Item One'},{id: 2, itemName: 'Item One'},]}

const {items, attachments, ...rest} = data;
const map = new Map(items.map(item => [item.id, {...item, attachments: []}]));
for (const attachment of attachments) {
    map.get(attachment.itemId).attachments.push(attachment);
}
const result = {...rest, items: [...map.values()]};

console.log(result);
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