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 to merge in a reducer two objects in one merging also a subfiled which is an array

I have the following snippet which uses a reduce and I cannot use another kind of loops, I have as a requirement to solve this by a reduce or a way which does not include a loop as for or forEach

CodeSandbox

As you will see I have an array of objects and inside it, I have 2 objects with the same studyId.

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

What I need is to merge the objects with the same studyId and the subfield siteIds in one array to have the following result

{ studyId: "ANNO5", siteIds: ["Paris", "Bon", "PLACEHOLDER", "Amsterdam", "Bruxelles" ] }

The siteIds also need to be unique I cannot have repeated the same siteId in the array

In the snippet, I tried with the reducer as I have that as a requirement but cannot figure out how to achieve the result I need.

Including the full desired output as was confusing a super comments

[
   // Here the merged with the same StudyId
  { studyId: "ANNO5", siteIds: ["Paris", "Bon", "PLACEHOLDER", "Amsterdam", "Bruxelles", "Paris"] },
  {
    studyId: "ANNO6",
    siteIds: ["Rome", "Torino", "PLACEHOLDER", "Milano"]
  },
  { studyId: "ANNO7", siteIds: undefined },
  { studyId: "ANNO8", siteIds: undefined }
];

as per undefined the requirement is similar to having something like this

siteIds: isEmpty(siteIds) ? undefined : uniq(siteIds),

When no siteIds we have undefined as per the above example

>Solution :

You can group the data by studyId using reduce and use Set to remove duplicate siteIds.

const siteIds = [
  { studyId: "ANNO5", siteIds: ["Paris", "Bon", "PLACEHOLDER"] },
  { studyId: "ANNO5", siteIds: ["Amsterdam", "Bruxelles", "PLACEHOLDER", "Paris"] },
  { studyId: "ANNO6", siteIds: ["Rome", "Torino", "PLACEHOLDER", "Milano"] },
  { studyId: "ANNO7", siteIds: undefined },
  { studyId: "ANNO8", siteIds: undefined },
];

const result = Object.values(
  siteIds.reduce((r, o) => {
    if (!r[o.studyId]) {
      r[o.studyId] = { ...o, siteIds: undefined };
    }
    if (o.siteIds) {
      (r[o.studyId].siteIds ??= []).push(...o.siteIds);
      r[o.studyId].siteIds = [...new Set(r[o.studyId].siteIds)];
    }
    return r;
  }, {})
);

console.log(result);

If you want to avoid creating sets in every iteration, then refer to the snippet below:

const siteIds = [
  { studyId: "ANNO5", siteIds: ["Paris", "Bon", "PLACEHOLDER"] },
  { studyId: "ANNO5", siteIds: ["Amsterdam", "Bruxelles", "PLACEHOLDER", "Paris"] },
  { studyId: "ANNO6", siteIds: ["Rome", "Torino", "PLACEHOLDER", "Milano"] },
  { studyId: "ANNO7", siteIds: undefined },
  { studyId: "ANNO8", siteIds: undefined },
];


const result = Object.values(
  siteIds.reduce((r, o) => {
    if (!r[o.studyId]) {
      r[o.studyId] = { ...o, siteIds: undefined };
    }
    if (o.siteIds) {
      (r[o.studyId].siteIds ??= []).push(...o.siteIds);
    }
    return r;
  }, {})
).map((o) => ({
  ...o,
  ...(o.siteIds && { siteIds: [...new Set(o.siteIds)] }),
}));

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