繁体   English   中英

如何从对象数组中根据最新时间戳将数据映射到新对象中

[英]How from an array of objects to map the data in a new object based on a latest timestamp

我有以下代码片段,其功能是将模拟数据重新映射到新的数据中,其中包含新字段和总计算。

为简单起见,使用了一个短数组和一个日期。

计算是关于一个状态有多少个 Id 并给出总数。

从 OBJ 中您可以看到statusType ,而我需要在一个对象中聚合相同的 status、studyId、label、siteId 并打印出 statusType 具有的 Id 总数。

该片段计算但错误

 const mockData = [{ id: "C10-TBX4", studyId: "TBX4", siteId: "USA-1", statusType: "INCOMPLETE", statusFrom: "2020-12-05T01:00:00.000Z", statusTo: "2020-12-05T02:00:00.000Z" }, { id: "C10-TBX4", studyId: "TBX4", siteId: "USA-1", statusType: "DROPOUT_PRESCREENER", eligible: true, statusFrom: "2020-12-05T02:00:00.000Z", statusTo: "2020-12-05T03:00:00.000Z" }, { id: "C10-TBX4", studyId: "TBX4", siteId: "USA-1", statusType: "INCOMPLETE", statusFrom: "2020-12-05T03:00:00.000Z", statusTo: null } ]; function endOfDay(time) { const date = new Date(time); date.setUTCHours(23, 59, 59, 999); return date; } const assignLabel = (statusType, eligible) => { if (statusType === "INCOMPLETE") return "pending"; if (statusType === "REJECTED_PRESCREENER") return "ineligible"; if (statusType === "DROPOUT_PRESCREENER" && eligible) return "eligible"; if (statusType === "DROPOUT_PRESCREENER" && !eligible) return "abandoned"; return "completed"; }; // This dates are generated from a fuction bases on which dates range we need // In this cas is just one day const batches = ["2020-12-05T00:00:00.000Z"]; const screeningNumbersCalculations = () => { const results = []; batches.forEach((t) => { const matchingStatusesTime = mockData.filter((s) => { return ( new Date(s.statusFrom) < endOfDay(t) && (s.statusTo === null || new Date(t) <= new Date(s.statusTo)) ); }); matchingStatusesTime.forEach((ms) => { const r = { days: [t], studyId: ms.studyId, siteId: ms.siteId, screeningStage: "SELF_ASSESSMENT", label: assignLabel(ms.statusType, ms.eligible), total: 1 }; const key = `${r.days}${r.studyId}${r.siteId}${r.label}`; if (!results[key]) results[key] = r; else results[key].total += 1; }); }); return Object.values(results); }; const screeningNumbers = screeningNumbersCalculations(); console.log(JSON.stringify(screeningNumbers, null, 2));

片段中的结果大约是 2 个对象,但预期结果应如下所示

{
          days: [ 2020-12-05T00:00:00.000Z ],
          studyId: 'TBX4',
          siteId: 'USA-1',
          screeningStage: 'SELF_ASSESSMENT',
          label: 'pending',
          total: 1
},

原因是那些对象在同一天具有相同的 ID,而变化的是状态。 在这种情况下,我应该只考虑也是当前状态的最新状态,而不是计算其他 2。

我现在不知道如何在我的实现中做到这一点。

目标是我在同一日期打印所有状态总数,但我需要考虑一个 ID 可以在同一天更改状态,所以我必须根据statusFrom的最后一个时间戳进行计算

我们可以根据日期排序,然后通过使用对象覆盖来省略重复项,然后评估对象的结果值。 希望能满足您的需求。

 const mockData = [{ id: "C10-TBX4", studyId: "TBX4", siteId: "USA-1", statusType: "INCOMPLETE", statusFrom: "2020-12-05T01:00:00.000Z", statusTo: "2020-12-05T02:00:00.000Z" }, { id: "C10-TBX4", studyId: "TBX4", siteId: "USA-1", statusType: "DROPOUT_PRESCREENER", eligible: true, statusFrom: "2020-12-05T02:00:00.000Z", statusTo: "2020-12-05T03:00:00.000Z" }, { id: "C10-TBX4", studyId: "TBX4", siteId: "USA-1", statusType: "INCOMPLETE", statusFrom: "2020-12-05T03:00:00.000Z", statusTo: null } ]; function endOfDay(time) { const date = new Date(time); date.setUTCHours(23, 59, 59, 999); return date; } const assignLabel = (statusType, eligible) => { if (statusType === "INCOMPLETE") return "pending"; if (statusType === "REJECTED_PRESCREENER") return "ineligible"; if (statusType === "DROPOUT_PRESCREENER" && eligible) return "eligible"; if (statusType === "DROPOUT_PRESCREENER" && !eligible) return "abandoned"; return "completed"; }; // This dates are generated from a fuction bases on which dates range we need // In this cas is just one day const batches = ["2020-12-05T00:00:00.000Z"]; const screeningNumbersCalculations = () => { const results = {}; // Dont use array since you are using it as dictionary Object. // Putting latest records at end so we can confidently overwrite with records of same day in next step mockData.sort((a, b) => endOfDay(a).getTime() - endOfDay(b).getTime()); const dateidMap = mockData.reduce((accum, item) => { accum[`${endOfDay(item).getTime()}.${item.id}`] = item; return accum; }, {}); batches.forEach(t => { // or filter matching times first and generate dateidMap later. const matchingStatusesTime = Object.values(dateidMap).filter((s) => { return ( new Date(s.statusFrom) < endOfDay(t) && (s.statusTo === null || new Date(t) <= new Date(s.statusTo)) ); }); matchingStatusesTime.forEach((ms) => { const key = `${t}${ms.studyId}${ms.siteId}${assignLabel(ms.statusType, ms.eligible)}`; if (!results[key]) { results[key] = { days: [t], studyId: ms.studyId, siteId: ms.siteId, screeningStage: "SELF_ASSESSMENT", label: assignLabel(ms.statusType, ms.eligible), total: 0 }; } results[key].total++; }); }); return Object.values(results); }; const screeningNumbers = screeningNumbersCalculations(); console.log(JSON.stringify(screeningNumbers, null, 2));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM