[英]How to reduce some data into a new array of objects?
更新我尝试了自己的解决方案,这就是我所做的也许可以做得更好
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);
我是使用 reduce 的新手,我在理解如何正确使用它时遇到了一些困难。
我想解决一个问题,我需要在具有不同形状的新 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,
},
},
];
为了学习,我能够创建一个计算总和的减速器,并且我做到了,但上述问题我很难开始并想理解它。
你可以尝试这样的事情:
请注意 - 我没有考虑验证/异常处理。 这只是对数据使用 reduce 的一种方式。 您还可以找到一种减少代码行的可爱方法 - 随意:-)
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 }
}
]
下面的currents
功能只是合并了相同 ID 的对象的当前值和totals
值。 因此,对于由 OP 提供的重复项(如Y
/ B
的重复项),相同属性的数值将被覆盖但不会相加。
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; }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.