提问人:user1352042 提问时间:11/8/2023 最后编辑:user1352042 更新时间:11/10/2023 访问量:90
使用 vanilla JavaScript 进行自定义数据聚合
Customized data aggregation using vanilla JavaScript
问:
你能帮我解决以下数据聚合问题吗?
这是我的初始数组:
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' },
];
我想根据值聚合 type 下的部分行。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);
答:
0赞
Nina Scholz
11/9/2023
#1
您可以取两组,并在第一次迭代中收集匹配的类型和其他类型。然后删除在集合中匹配的类型,因为这些类型应位于结果集中。other
最后检查,如果集合中只有一种类型,则将此类型也添加到结果中。other
对于所有其他不匹配类型,请按 type 分组。'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 } of data) {
if (match.has(type)) {
result.push({ date, type, casualties, state, country });
continue;
}
if (others[date]) others[date].casualties += casualties;
else result.push(others[date] = { date, type: 'other', casualties, state, country });
}
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; }
评论
0赞
user1352042
11/9/2023
感谢您解决此问题!我只需要从 for 循环中删除,使代码输出反映预期结果。site
0赞
Nina Scholz
11/9/2023
@user1352042,请参阅编辑。
评论
'A'
casualtiesThreshold = 13
A
results
casualties
casualtiesThreshold
B
D
results
casualties