ES6实现Group By和SUM

时间:2018-03-26 06:04:23

标签: javascript ecmascript-6

我有一组具有以下属性的对象: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 }
]

4 个答案:

答案 0 :(得分:4)

您可以将数组减少到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)

答案 1 :(得分:1)

您可以像这样使用.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; }




有用的资源:

答案 2 :(得分:0)

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

它很慢而且只是为了好玩:)

答案 3 :(得分:0)

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