一个js数组分类求和算法

需求详情:一个数组内有N个元素,元素有类型、名称、数量1、数量2等属性,计算出各类型元素的数量、数量1、数量2的和。

实际需求就是做出下图这样一个表格,各类型的合计信息用红色字体显示:

原始数据格式如下:

const rawData = [
      { type: '类型A', name: '名称1', count1: 13, count2: 24, count3: 34 },
      { type: '类型A', name: '名称2', count1: 13, count2: 24, count3: 34 },
      { type: '类型A', name: '名称3', count1: 13, count2: 24, count3: 34 },
      { type: '类型B', name: '名称4', count1: 12, count2: 23, count3: 33 },
      { type: '类型B', name: '名称5', count1: 12, count2: 23, count3: 33 },
      { type: '类型B', name: '名称6', count1: 12, count2: 23, count3: 33 },
      { type: '类型C', name: '名称7', count1: 11, count2: 25, count3: 35 },
      { type: '类型C', name: '名称8', count1: 11, count2: 25, count3: 35 }
    ]

算法思路:遍历该数组,按类型生成一个二维数组,再遍历该二级数组及其子元素,每遍历完一个类型的子元素后求和,并创建一个新的元素存储该类型元素的和,最后生成一个包含各类型元素数量的新数组,实现代码如下:

calcSum(arr) {
      const newArr = [];
      arr.forEach((item, index) => {
        let flag = 0;
        let k = 0;
        newArr.forEach((newItem, j) => {
          if (newArr[j][0].type === arr[index].type) {
            flag = 1;
            k = j;
          }
        });
        if (flag) {
          newArr[k].push(arr[index])
        } else {
          const tempArr = [];
          tempArr.push(arr[index]);
          newArr.push(tempArr);
        }
      });

      const result = []
      newArr.forEach(subArr => {
        let sum_name = 0;
        let sum_count1 = 0;
        let sum_count2 = 0;
        let sum_count3 = 0;

        subArr.forEach(subItem => {
          sum_name += 1;
          sum_count1 += subItem.count1;
          sum_count2 += subItem.count2;
          sum_count3 += subItem.count3;
          result.push(subItem);
        });
        result.push({
          type: subArr[0].type,
           name: sum_name,
           count1: sum_count1,
           count2: sum_count2,
           count3: sum_count3,
           isSumRow: true //该属性标记为求和行
        })
      })
      return result;
    }

生产的二维数组格式如下:

 newArr = [
        [
          { 'type': '类型A', 'name': '名称1', 'count1': 13, 'count2': 24, 'count3': 34 },
          { 'type': '类型A', 'name': '名称2', 'count1': 13, 'count2': 24, 'count3': 34 },
          { 'type': '类型A', 'name': '名称3', 'count1': 13, 'count2': 24, 'count3': 34 }
        ],
        [
          { 'type': '类型B', 'name': '名称4', 'count1': 12, 'count2': 23, 'count3': 33 },
          { 'type': '类型B', 'name': '名称5', 'count1': 12, 'count2': 23, 'count3': 33 },
          { 'type': '类型B', 'name': '名称6', 'count1': 12, 'count2': 23, 'count3': 33 }
        ],
        [
          { 'type': '类型C', 'name': '名称7', 'count1': 11, 'count2': 25, 'count3': 35 },
          { 'type': '类型C', 'name': '名称8', 'count1': 11, 'count2': 25, 'count3': 35 }
        ]
      ]

最终数据格式如下,为了与普通的数据区分开,给求和的数据加上了一个isSumRow属性,用来生成一个className来标红:

 result = [
            { 'type': '类型A', 'name': '名称1', 'count1': 13, 'count2': 24, 'count3': 34 },
            { 'type': '类型A', 'name': '名称2', 'count1': 13, 'count2': 24, 'count3': 34 },
            { 'type': '类型A', 'name': '名称3', 'count1': 13, 'count2': 24, 'count3': 34 },
            { 'type': '类型A', 'name': 3, 'count1': 39, 'count2': 72, 'count3': 102, 'isSumRow': true },
            { 'type': '类型B', 'name': '名称4', 'count1': 12, 'count2': 23, 'count3': 33 },
            { 'type': '类型B', 'name': '名称5', 'count1': 12, 'count2': 23, 'count3': 33 },
            { 'type': '类型B', 'name': '名称6', 'count1': 12, 'count2': 23, 'count3': 33 },
            { 'type': '类型B', 'name': 3, 'count1': 36, 'count2': 69, 'count3': 99, 'isSumRow': true },
            { 'type': '类型C', 'name': '名称7', 'count1': 11, 'count2': 25, 'count3': 35 },
            { 'type': '类型C', 'name': '名称8', 'count1': 11, 'count2': 25, 'count3': 35 },
            { 'type': '类型C', 'name': 2, 'count1': 22, 'count2': 50, 'count3': 70, 'isSumRow': true }
          ]

 上一篇
小米手机刷MIUI国际版折腾记录 小米手机刷MIUI国际版折腾记录
本人现在使用的是一部红米NOTE5,配置是高通骁龙636+6G+64G,之前用的系统都是MIUI9,一直都没更新过,最近更新了MIUI11,就准备升级一下,更新了国行的系统之后发现广告太多实在受不了。就刷了个MIUI国际版,记录一下折腾的过
2020-04-07
下一篇 
使用js-xlsx插件导出多级表头excel 使用js-xlsx插件导出多级表头excel
最近项目里有这么一个需求,把一个多级表头的table导出为excel格式。然后在网上找到一篇文章:js-xlsx导出自定义合并列头实现思路,我按照他的教程操作之后发现比较繁琐,这篇文章的思路就是就是新建一个excel,然后用js来读取它的多
2020-02-27