您能帮我解决以下数据聚合问题吗?
这是我的初始数组:
const data = [
{ date: '2023-11-01', type: 'A', casualties: 10, state: 'NY', country: 'USA', site: 'hash1' },
{ date: '2023-11-01', type: 'B', casualties: 5, state: 'NY', country: 'USA', site: 'hash2' },
{ date: '2023-11-02', type: 'A', casualties: 15, state: 'NY', country: 'USA', site: 'hash3' },
{ date: '2023-11-01', type: 'C', casualties: 20, state: 'NY', country: 'USA', site: 'hash4' },
{ date: '2023-11-02', type: 'B', casualties: 8, state: 'NY', country: 'USA', site: 'hash5' },
{ date: '2023-11-03', type: 'A', casualties: 25, state: 'NY', country: 'USA', site: 'hash6' },
{ date: '2023-11-01', type: 'D', casualties: 12, state: 'NY', country: 'USA', site: 'hash7' },
];
我想根据
other
值聚合 casualties
类型下的部分行。
如果给定
type
的所有日期的 casualties
等于或高于某个阈值,则它应该是 results
数组的一部分。
如果给定
type
的 casualties
低于所有日期的阈值,但它是唯一低于阈值的 type
,则它将成为 results
数组的一部分。
如果所有日期中有两个或多个
types
的 casualties
低于特定阈值,
它们不应该是 results
数组的一部分。对于这种情况,
casualties
将针对每个日期进行求和,并且 type
值应为 other
。
otherCasualties
数组应包含 types
低于所有日期阈值的所有 casualties
。
示例:
如果
casualtiesThreshold
是 9
,则 results
数组应该是:
results = [
{ date: '2023-11-01', type: 'A', casualties: 10, state: 'NY', country: 'USA' },
{ date: '2023-11-01', type: 'B', casualties: 5, state: 'NY', country: 'USA' },
{ date: '2023-11-02', type: 'A', casualties: 15, state: 'NY', country: 'USA' },
{ date: '2023-11-01', type: 'C', casualties: 20, state: 'NY', country: 'USA' },
{ date: '2023-11-02', type: 'B', casualties: 8, state: 'NY', country: 'USA' },
{ date: '2023-11-03', type: 'A', casualties: 25, state: 'NY', country: 'USA' },
{ date: '2023-11-01', type: 'D', casualties: 12, state: 'NY', country: 'USA' },
];
并且
otherCasualties
数组应该是 []
。
如果
casualtiesThreshold
是 13
,则 results
数组应该是:
results = [
{ date: '2023-11-01', type: 'A', casualties: 10, state: 'NY', country: 'USA'},
{ date: '2023-11-01', type: 'other', casualties: 17, state: 'NY', country: 'USA' },
{ date: '2023-11-02', type: 'A', casualties: 15, state: 'NY', country: 'USA' },
{ date: '2023-11-01', type: 'C', casualties: 20, state: 'NY', country: 'USA' },
{ date: '2023-11-02', type: 'other', casualties: 8, state: 'NY', country: 'USA' },
{ date: '2023-11-03', type: 'A', casualties: 25, state: 'NY', country: 'USA' },
];
并且
otherCasualties
数组应该是 ['B', 'D']
。
这是我尝试过的:
function processCasualties(data, casualtiesThreshold) {
const results = [];
const otherCasualties = [];
const groupedData = data.reduce((acc, item) => {
const key = item.type;
if (!acc[key]) {
acc[key] = [];
}
acc[key].push(item);
return acc;
}, {});
const types = Object.keys(groupedData);
types.forEach(type => {
const typeData = groupedData[type];
const totalCasualties = typeData.reduce((acc, item) => acc + item.casualties, 0);
const allDatesBelowThreshold = typeData.every(item => item.casualties < casualtiesThreshold);
if (totalCasualties >= casualtiesThreshold || (allDatesBelowThreshold && types.length === 1)) {
results.push(...typeData.map(item => ({
date: item.date,
type: item.type,
casualties: item.casualties,
state: item.state,
country: item.country,
})));
} else if (allDatesBelowThreshold) {
otherCasualties.push(type);
} else {
results.push(...typeData.map(item => ({
date: item.date,
type: 'other',
casualties: totalCasualties,
state: item.state,
country: item.country,
})));
}
});
return { results, otherCasualties };
}
const casualtiesThreshold = 13;
const { results, otherCasualties } = processCasualties(data, casualtiesThreshold);
console.log(results);
console.log(otherCasualties);
您可以采取两组并在第一次迭代中收集匹配的类型和其他类型。然后删除
other
集中匹配的类型,因为这些类型应该在结果集中。
最后检查
other
集中是否只有一种类型,然后将该类型也添加到结果中。
对于所有其他不匹配类型,采用
'other'
作为类型,按 date
分组。
const
fn = (data, threshold) => {
const
result = [],
other = new Set,
match = new Set,
others = {};
for (const { type, casualties } of data) [other, match][+(casualties >= threshold)].add(type);
match.forEach(Set.prototype.delete, other);
if (other.size === 1) {
match.add(...other);
other.clear();
}
for (const { date, type, casualties, state, country, site } of data) {
if (match.has(type)) {
result.push({ date, type, casualties, state, country, site });
} else {
if (others[date]) others[date].casualties += casualties;
else result.push(others[date] = { date, type: 'other', casualties, state, country, site });
}
}
return { result, otherCasualties: [...other] };
},
data = [{ date: '2023-11-01', type: 'A', casualties: 10, state: 'NY', country: 'USA', site: 'hash1' }, { date: '2023-11-01', type: 'B', casualties: 5, state: 'NY', country: 'USA', site: 'hash2' }, { date: '2023-11-02', type: 'A', casualties: 15, state: 'NY', country: 'USA', site: 'hash3' }, { date: '2023-11-01', type: 'C', casualties: 20, state: 'NY', country: 'USA', site: 'hash4' }, { date: '2023-11-02', type: 'B', casualties: 8, state: 'NY', country: 'USA', site: 'hash5' }, { date: '2023-11-03', type: 'A', casualties: 25, state: 'NY', country: 'USA', site: 'hash6' }, { date: '2023-11-01', type: 'D', casualties: 12, state: 'NY', country: 'USA', site: 'hash7' }];
console.log(fn(data, 9));
console.log(fn(data, 13));
.as-console-wrapper { max-height: 100% !important; top: 0; }