Home > Blockchain >  How to use JS reduce to merge two arrays of objets into one array of objects where a specific key/va
How to use JS reduce to merge two arrays of objets into one array of objects where a specific key/va

Time:10-17

I'm trying to understand how to merge 2 arrays of objects into 1 array of objects and combine together where a specific key value match in both arrays

I have an example of what my goal is but no snippet as I don't know how to start and make it

The 2 objects

const objA = [
  {
    "id": "DEMO-1",
    "siteId": "01",
  },
  {
    "id": "DEMO-2",
    "siteId": "02",
  },
  {
    "id": "DEMO-3",
    "siteId": "05",
  },
  {
    "id": "DEMO-4",
    "siteId": null,
  },
  {
    "id": "DEMO-5",
    "siteId": null,
  },
  {
    "id": "DEMO-6",
    "siteId": "05",
  },
  {
    "id": "DEMO-7",
    "siteId": "02",
  },
];

const objB = [
  { siteId: '01', principalInvestigator: { name: 'Jake' } },
  { siteId: '02', principalInvestigator: { name: 'Claudia' } },
  { siteId: '05', principalInvestigator: null },
];

These 2 objects have to be combined together when we have a match at the same siteId

The result should be a new array of objects and the cases are as follow:

  1. We have a match objA.siteId === objB.siteId then the result will be objA objB.principalInvestigator
  2. there is no match then we add principalInvestigator: null
const result = [
  {
    "id": "DEMO-1",
    "siteId": "01",
    "principalInvestigator": { name: 'Jake' }
  },
  {
    "id": "DEMO-2",
    "siteId": "02",
    "principalInvestigator": { name: 'Claudia' }
  },
  {
    "id": "DEMO-3",
    "siteId": "05",
    "principalInvestigator": null
  },
  {
    "id": "DEMO-4",
    "siteId": null,
    "principalInvestigator": null
  },
  {
    "id": "DEMO-5",
    "siteId": null,
    "principalInvestigator": null
  },
  {
    "id": "DEMO-6",
    "siteId": "05",
    "principalInvestigator": null
  },
  {
    "id": "DEMO-7",
    "siteId": "02",
    "principalInvestigator": { name: 'Claudia' }
  },
]

CodePudding user response:

You could create a lookup map for the second object (keyed by siteId) and then map the first array to extended objects for which you will look up the principalInvestigator data from the map:

const objA = [{"id": "DEMO-1","siteId": "01",},{"id": "DEMO-2","siteId": "02",},{"id": "DEMO-3","siteId": "05",},{"id": "DEMO-4","siteId": null,},{"id": "DEMO-5","siteId": null,},{"id": "DEMO-6","siteId": "05",},{"id": "DEMO-7","siteId": "02",},];

const objB = [
  { siteId: '01', principalInvestigator: { name: 'Jake' } },
  { siteId: '02', principalInvestigator: { name: 'Claudia' } },
  { siteId: '05', principalInvestigator: null },
];

const map = new Map(objB.map(o => [o.siteId, o.principalInvestigator]));
const result = objA.map(o => ({...o, prinicalInvestigator: map.get(o.siteId) ?? null}));
console.log(result);

Note that if multiple objects in the first array have the same siteId, then their new prinicalInvestigator properties will reference the same object.

CodePudding user response:

For each a in objA use find to locate the corresponding object in objB:

result = objA.map(a => ({...a,
    ...(objB.find(b => b.siteId === a.siteId) ?? {principalInvestigator: null})
}))
  • Related