如何将一些数据减少到新的对象中?

发布于 2025-01-30 15:38:42 字数 2233 浏览 1 评论 0原文

更新 我尝试了自己的解决方案,这是我所做的,也许可以做得更好

const dbData = [{
    studyId: 'X',
    siteId: 'A',
    day: '2000-01-01',
    status: 'PENDING_CALLCENTER',
    current: 5,
    total: 17,
  },
  {
    studyId: 'X',
    siteId: 'A',
    day: '2000-01-01',
    status: 'PENDING_SITE',
    current: 3,
    total: 9,
  },
  {
    studyId: 'Y',
    siteId: 'B',
    day: '2000-01-01',
    status: 'PENDING_SITE',
    current: 3,
    total: 9,
  },
  {
    studyId: 'Y',
    siteId: 'B',
    day: '2000-01-01',
    status: 'PENDING_SITE',
    current: 3,
    total: 9,
  },
  {
    studyId: 'Y',
    siteId: 'B',
    day: '2000-01-01',
    status: 'PENDING_CALLCENTER',
    current: 3,
    total: 9,
  },
];


const reduced = dbData.reduce((acc, row) => {
  const {
    studyId,
    siteId,
    status,
    current,
    total
  } = row;
  const idx = acc.findIndex(x => studyId === x.studyId && siteId === x.siteId);
  const item = idx === -1 ? {
    studyId,
    siteId,
    currents: {},
    totals: {}
  } : { ...acc[idx]
  };
  item.currents[status] = item.currents[status] ? item.currents[status] + current : current;
  item.totals[status] = item.totals[status] ? item.totals[status] + total : total;
  if (idx === -1) {
    acc.push(item);
  } else {
    acc[idx] = item;
  }
  return acc;
}, []);

console.log(reduced);

我是使用减少的新手,并且在理解如何正确使用它时遇到了一些困难。

我想解决一个问题,我需要在具有不同形状的新的OBJ中减少一些数据。

我有一些数据,

[
      {
        studyId: 'X',
        siteId: 'A',
        day: '2000-01-01',
        status: 'PENDING_CALLCENTER',
        current: 5,
        total: 17,
      },
      {
        studyId: 'X',
        siteId: 'A',
        day: '2000-01-01',
        status: 'PENDING_SITE',
        current: 3,
        total: 9,
      },
    ];

我想将其简化为新数据,

[
      {
        studyId: 'X',
        siteId: 'A',
        currents: {
          PENDING_CALLCENTER: 5,
          PENDING_SITE: 3,
        },
        totals: {
          PENDING_CALLCENTER: 17,
          PENDING_SITE: 9,
        },
      },
    ];

以了解我能够创建一个降低器来计算总和,但是我做到了,但是上述问题我很难开始并想理解它。

update
I tried my own solution and this is what I did maybe can be done better

const dbData = [{
    studyId: 'X',
    siteId: 'A',
    day: '2000-01-01',
    status: 'PENDING_CALLCENTER',
    current: 5,
    total: 17,
  },
  {
    studyId: 'X',
    siteId: 'A',
    day: '2000-01-01',
    status: 'PENDING_SITE',
    current: 3,
    total: 9,
  },
  {
    studyId: 'Y',
    siteId: 'B',
    day: '2000-01-01',
    status: 'PENDING_SITE',
    current: 3,
    total: 9,
  },
  {
    studyId: 'Y',
    siteId: 'B',
    day: '2000-01-01',
    status: 'PENDING_SITE',
    current: 3,
    total: 9,
  },
  {
    studyId: 'Y',
    siteId: 'B',
    day: '2000-01-01',
    status: 'PENDING_CALLCENTER',
    current: 3,
    total: 9,
  },
];


const reduced = dbData.reduce((acc, row) => {
  const {
    studyId,
    siteId,
    status,
    current,
    total
  } = row;
  const idx = acc.findIndex(x => studyId === x.studyId && siteId === x.siteId);
  const item = idx === -1 ? {
    studyId,
    siteId,
    currents: {},
    totals: {}
  } : { ...acc[idx]
  };
  item.currents[status] = item.currents[status] ? item.currents[status] + current : current;
  item.totals[status] = item.totals[status] ? item.totals[status] + total : total;
  if (idx === -1) {
    acc.push(item);
  } else {
    acc[idx] = item;
  }
  return acc;
}, []);

console.log(reduced);

I'm new to using reduce and I have some difficulties understanding how to use it correctly.

I would like to solve a problem where I need to reduce some data in a new array of obj with a different shape.

I have some data

[
      {
        studyId: 'X',
        siteId: 'A',
        day: '2000-01-01',
        status: 'PENDING_CALLCENTER',
        current: 5,
        total: 17,
      },
      {
        studyId: 'X',
        siteId: 'A',
        day: '2000-01-01',
        status: 'PENDING_SITE',
        current: 3,
        total: 9,
      },
    ];

I want to reduce this to this new data

[
      {
        studyId: 'X',
        siteId: 'A',
        currents: {
          PENDING_CALLCENTER: 5,
          PENDING_SITE: 3,
        },
        totals: {
          PENDING_CALLCENTER: 17,
          PENDING_SITE: 9,
        },
      },
    ];

To learn I was able to create a reducer which calc sum and that I did it but the above problem I have just difficulties to start and want to understand it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

初相遇 2025-02-06 15:38:42

您可以尝试这样的事情:

请注意 - 我没有考虑验证/异常处理。这只是使用减少数据的一种方法。您还可以找到一种可爱的减少代码行的方式 - 自由:-)

const arr = [
  {
    studyId: 'X',
    siteId: 'A',
    day: '2000-01-01',
    status: 'PENDING_CALLCENTER',
    current: 5,
    total: 17,
  },
  {
    studyId: 'X',
    siteId: 'A',
    day: '2000-01-01',
    status: 'PENDING_SITE',
    current: 3,
    total: 9,
  },
];

const res = arr.reduce((accum, curr) => {
  const exist = accum.find(e => e.studyId === curr.studyId && e.siteId === curr.siteId);
  if (exist) {
    exist.currents[curr.status] += curr.current;
    exist.totals[curr.status] += curr.total;
  } else {
    const elem = {
      studyId: curr.studyId,
      siteId: curr.siteId,
      currents: {
        PENDING_CALLCENTER: 0,
        PENDING_SITE: 0,
      },
      totals: {
        PENDING_CALLCENTER: 0,
        PENDING_SITE: 0,
      }
    }
    elem.currents[curr.status] = curr.current;
    elem.totals[curr.status] = curr.total;
    accum.push(elem);
  }
  return accum;
}, []);

console.log(res);

输出:

[
  {
    studyId: 'X',
    siteId: 'A',
    currents: { PENDING_CALLCENTER: 5, PENDING_SITE: 3 },
    totals: { PENDING_CALLCENTER: 17, PENDING_SITE: 9 }
  }
]

You can try something like this :

Please note - I haven't considered validation/exception handling. This is just one way of using a reduce for your data. You could also find a cute way of reducing lines of code - feel free :-)

const arr = [
  {
    studyId: 'X',
    siteId: 'A',
    day: '2000-01-01',
    status: 'PENDING_CALLCENTER',
    current: 5,
    total: 17,
  },
  {
    studyId: 'X',
    siteId: 'A',
    day: '2000-01-01',
    status: 'PENDING_SITE',
    current: 3,
    total: 9,
  },
];

const res = arr.reduce((accum, curr) => {
  const exist = accum.find(e => e.studyId === curr.studyId && e.siteId === curr.siteId);
  if (exist) {
    exist.currents[curr.status] += curr.current;
    exist.totals[curr.status] += curr.total;
  } else {
    const elem = {
      studyId: curr.studyId,
      siteId: curr.siteId,
      currents: {
        PENDING_CALLCENTER: 0,
        PENDING_SITE: 0,
      },
      totals: {
        PENDING_CALLCENTER: 0,
        PENDING_SITE: 0,
      }
    }
    elem.currents[curr.status] = curr.current;
    elem.totals[curr.status] = curr.total;
    accum.push(elem);
  }
  return accum;
}, []);

console.log(res);

Output:

[
  {
    studyId: 'X',
    siteId: 'A',
    currents: { PENDING_CALLCENTER: 5, PENDING_SITE: 3 },
    totals: { PENDING_CALLCENTER: 17, PENDING_SITE: 9 }
  }
]

绅士风度i 2025-02-06 15:38:42

以下还原功能仅合并currentstotals同一ID的对象的值。因此,对于y/b的重复项,例如OP提供的重复项,相同属性的数值将被覆盖,但不会汇总。

function mergeCurrentsAndTotalsOfSameIds({ lookup = new Map, result }, item) {
  const { studyId, siteId, status, current, total } = item;
  const mergerKey = [studyId, '_###_', siteId].join('');

  let merger = lookup.get(mergerKey);
  if (!merger) {

    merger = { studyId, siteId, currents: {}, totals: {} };

    lookup.set(mergerKey, merger);
    result.push(merger);
  }
  merger.currents[status] = current;
  merger.totals[status] = total;

  return { lookup, result };
}

const dbData = [{
  studyId: 'X',
  siteId: 'A',
  day: '2000-01-01',
  status: 'PENDING_CALLCENTER',
  current: 5,
  total: 17,
}, {
  studyId: 'X',
  siteId: 'A',
  day: '2000-01-01',
  status: 'PENDING_SITE',
  current: 3,
  total: 9,
}, {
  studyId: 'Y',
  siteId: 'B',
  day: '2000-01-01',
  status: 'PENDING_SITE',
  current: 3,
  total: 9,
}, {
  studyId: 'Y',
  siteId: 'B',
  day: '2000-01-01',
  status: 'PENDING_SITE',
  current: 3,
  total: 9,
}, {
  studyId: 'Y',
  siteId: 'B',
  day: '2000-01-01',
  status: 'PENDING_CALLCENTER',
  current: 3,
  total: 9,
}];

const { result: mergedData } = dbData
  .reduce(mergeCurrentsAndTotalsOfSameIds, {result: [] })

console.log({ mergedData, dbData });
.as-console-wrapper { min-height: 100%!important; top: 0; }

The following reducer functionality just merges the currents and totals values of objects of same IDs. Thus, for duplicate items like provided by the OP with a duplicate for Y/B, number values for same properties will be overwritten but not summed-up.

function mergeCurrentsAndTotalsOfSameIds({ lookup = new Map, result }, item) {
  const { studyId, siteId, status, current, total } = item;
  const mergerKey = [studyId, '_###_', siteId].join('');

  let merger = lookup.get(mergerKey);
  if (!merger) {

    merger = { studyId, siteId, currents: {}, totals: {} };

    lookup.set(mergerKey, merger);
    result.push(merger);
  }
  merger.currents[status] = current;
  merger.totals[status] = total;

  return { lookup, result };
}

const dbData = [{
  studyId: 'X',
  siteId: 'A',
  day: '2000-01-01',
  status: 'PENDING_CALLCENTER',
  current: 5,
  total: 17,
}, {
  studyId: 'X',
  siteId: 'A',
  day: '2000-01-01',
  status: 'PENDING_SITE',
  current: 3,
  total: 9,
}, {
  studyId: 'Y',
  siteId: 'B',
  day: '2000-01-01',
  status: 'PENDING_SITE',
  current: 3,
  total: 9,
}, {
  studyId: 'Y',
  siteId: 'B',
  day: '2000-01-01',
  status: 'PENDING_SITE',
  current: 3,
  total: 9,
}, {
  studyId: 'Y',
  siteId: 'B',
  day: '2000-01-01',
  status: 'PENDING_CALLCENTER',
  current: 3,
  total: 9,
}];

const { result: mergedData } = dbData
  .reduce(mergeCurrentsAndTotalsOfSameIds, {result: [] })

console.log({ mergedData, dbData });
.as-console-wrapper { min-height: 100%!important; top: 0; }

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文