如何在一个 reducer 中合并两个对象,同时合并一个子文件,它是一个数组

How to merge in a reducer two objects in one merging also a subfiled which is an array

我有以下使用 reduce 的代码片段,我不能使用另一种循环,我需要通过 reduce 或不包含 a 的方式来解决这个问题循环为 forforEach

CodeSandbox

正如您将看到的,我有一个对象数组,在其中,我有 2 个具有相同 studyId.

的对象

我需要的是将具有相同 studyId 和子字段 siteIds 的对象合并到一个数组中以获得以下结果

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

siteIds 也必须是唯一的我不能在数组中重复相同的 siteId

在代码片段中,我尝试使用减速器,因为我有这个要求,但无法弄清楚如何实现我需要的结果。

包含完整的所需输出,这让超级评论感到困惑

[
   // 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 }
];

根据 undefined 要求类似于这样的东西

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

如果没有 siteIds 我们根据上面的例子没有定义

您可以使用 reducestudyId 对数据进行分组,并使用 Set 删除重复项 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);

如果您想避免在每次迭代中都创建集合,请参考下面的代码片段:

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