【问题标题】:ES6 Implementation of Group By and SUMGroup By 和 SUM 的 ES6 实现
【发布时间】:2018-03-26 06:04:22
【问题描述】:

我有一组具有以下属性的对象:material_no、material_name、qty。

let data = [
  { material_no: '1001', material_name: 'Material 1', qty: 100 },
  { material_no: '1001', material_name: 'Material 1', qty: 50 },
  { material_no: '1002', material_name: 'Material 2', qty: 44 },
  { material_no: '1003', material_name: 'Material 3', qty: 125 },
  { material_no: '1002', material_name: 'Material 2', qty: 59 },
  { material_no: '1004', material_name: 'Material 4', qty: 999 },
  { material_no: '1005', material_name: 'Material 5', qty: 80 },
  { material_no: '1005', material_name: 'Material 5', qty: 66 }
]

如何返回按其 material_no/material_name 分组的对象数组以及具有相同 material_no/material_name 的数量之和?

[
  { material_no: '1001', material_name: 'Material 1', qty: 150 },
  { material_no: '1002', material_name: 'Material 2', qty: 103 },
  { material_no: '1003', material_name: 'Material 3', qty: 125 },
  { material_no: '1004', material_name: 'Material 4', qty: 999 },
  { material_no: '1005', material_name: 'Material 5', qty: 146 }
]

【问题讨论】:

  • 到目前为止你有没有尝试过?能否提供示例数据和预期输出?
  • @nem035 我添加了示例和预期的输出。我在必须选择是否应该使用 filter、map、reduce 或 Object.assign 之间陷入困境。

标签: javascript ecmascript-6


【解决方案1】:

您可以将数组缩减为 Map,该数组将项目总数存储为 material_no。然后将地图值提取到数组中。

let data = [
  { material_no: '1001', material_name: 'Material 1', qty: 100 },
  { material_no: '1001', material_name: 'Material 1', qty: 50 },
  { material_no: '1002', material_name: 'Material 2', qty: 44 },
  { material_no: '1003', material_name: 'Material 3', qty: 125 },
  { material_no: '1002', material_name: 'Material 2', qty: 59 },
  { material_no: '1004', material_name: 'Material 4', qty: 999 },
  { material_no: '1005', material_name: 'Material 5', qty: 80 },
  { material_no: '1005', material_name: 'Material 5', qty: 66 }
]

const sums = [
  ...data.reduce(
    (map, item) => {
      const { material_no: key, qty } = item;
      const prev = map.get(key);
      
      if(prev) {
        prev.qty += qty
      } else {
        map.set(key, Object.assign({}, item))
      }
      
      return map
    },
    new Map()
  ).values()
]

console.log(sums)

【讨论】:

    【解决方案2】:

    你可以像这样使用.reduce()

    let data = [{ material_no: '1001', material_name: 'Material 1', qty: 100 },{ material_no: '1001', material_name: 'Material 1', qty: 50 },{ material_no: '1002', material_name: 'Material 2', qty: 44 },{ material_no: '1003', material_name: 'Material 3', qty: 125 },{ material_no: '1002', material_name: 'Material 2', qty: 59 },{ material_no: '1004', material_name: 'Material 4', qty: 999 },{ material_no: '1005', material_name: 'Material 5', qty: 80 },{ material_no: '1005', material_name: 'Material 5', qty: 66 }];
    
    let result = Object.values(
                   data.reduce((a, c) => (
                     a[c.material_no] = a[c.material_no] ?
                     (a[c.material_no].qty += c.qty, a[c.material_no]) :
                     c, a), {}
                   )
                 );
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    有用的资源:

    【讨论】:

    • 这太美了!
    【解决方案3】:
    data
        .sort((a, b) => a.material_no - b.material_no)
        .map(({material_no, material_name, qty}, index, arr) => ({
            material_no,
            material_name,
            qty: qty + (material_no === (arr[index - 1] || {}).material_no && arr[index - 1].qty)
        }))
        .filter(({material_no}, index, arr) => material_no !== (arr[index + 1] || {}).material_no);
    

    它很慢,只是为了好玩:)

    【讨论】:

      【解决方案4】:
      let data = [
        { material_no: '1001', material_name: 'Material 1', qty: 100 },
        { material_no: '1001', material_name: 'Material 1', qty: 50 },
        { material_no: '1002', material_name: 'Material 2', qty: 44 },
        { material_no: '1003', material_name: 'Material 3', qty: 125 },
        { material_no: '1002', material_name: 'Material 2', qty: 59 },
        { material_no: '1004', material_name: 'Material 4', qty: 999 },
        { material_no: '1005', material_name: 'Material 5', qty: 80 },
        { material_no: '1005', material_name: 'Material 5', qty: 66 }
      ];
      
      let accumulation = data.reduce((total, val, index)=>{
        let foundItemIndex = total.findIndex((obj)=>obj.material_no == val.material_no);
        if(foundItemIndex < 0) total.push(val) 
        else total[foundItemIndex].qty += val.qty;
        return total;
      }, []);
      
      console.log(accumulation);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-01-19
        • 1970-01-01
        • 2021-01-30
        • 2021-05-09
        • 2016-06-21
        • 2012-09-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多