你能帮我解决下面的数据聚合问题吗?

以下是我的初始数组:

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' },
];

我想根据casualties的值聚合类型other下的部分行.

如果给定的type在所有日期都有casualties等于或大于某个阈值,则它应该是results数组的一部分.

如果给定的type在所有日期都低于阈值casualties,但它是唯一低于阈值的type,则它将成为results数组的一部分.

如果两个或更多types在所有日期具有低于特定阈值的casualties, 它们不应该是results数组的一部分.对于此方案, casualties将 for each 日期求和,type值应为other.

otherCasualties数组应该包含所有日期的casualties低于阈值的所有types.

示例:

如果casualtiesThreshold9,则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数组应该是[].

如果casualtiesThreshold13,则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'].

这就是我try 过的:

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 } 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; }

Javascript相关问答推荐

使用reaction创建可排序的表不起作用

Math.random超出了最大调用堆栈

TestCafe预计文本等于以下内容之一

React:如何将表格收件箱正确渲染为表格主体内的组件?

获取表格的左滚动位置

如何修复循环HTML元素附加函数中的问题?

D3多线图显示1线而不是3线

按钮未放置在html dis位置

togglePopover()不打开但不关闭原生HTML popover'

Angular 订阅部分相互依赖并返回数组多个异步Http调用

编辑文本无响应.onClick(扩展脚本)

将核心模块导入另一个组件模块时存在多个主题

如何发送从REST Api收到的PNG数据响应

第二次更新文本输入字段后,Reaction崩溃

Use Location位置成员在HashRouter内为空

邮箱密码重置链接不适用于已部署的React应用程序

如何使本地html页面在重新加载时保持当前可隐藏部分的打开状态?

图表4-堆叠线和条形图之间的填充区域

Jexl to LowerCase()和Replace()

JAVASCRIPT SWITCH CASE语句:当表达式为';ALL';