我如何“总结”这样的对象数组?

时间:2017-07-24 15:51:09

标签: javascript sum lodash

我有一些这样的数据(简化):

sales: [
    {
        'quantity': 20,
        'amount': 40,
        'product': {
            'id': 1
            'category': 'Chemical',
            'subcategory': 'Herbicide'
        }
    },
    {
        'quantity': 10,
        'amount': 70,
        'product': {
            'id': 1
            'category': 'Chemical',
            'subcategory': 'Herbicide'
        }
    },
    {
        'quantity': 30,
        'amount': 60,
        'product': {
            'id': 2
            'category': 'Seed',
            'subcategory': 'Corn'
        }
    }
]

我希望按product.id对数据进行分组,并将quantityamount相加,并保持相同categorysubcategory(这将是同样适用于所有相同的产品ID)

所以基本上我希望我的数据看起来像这样:

filteredSum: [
    {
        'quantity': 30,
        'amount': 110,
        'product': {
            'category': 'Chemical',
            'subcategory': 'Herbicide'
        }
    },
    {
        'quantity': 30,
        'amount': 60,
        'product': {
            'category': 'Seed',
            'subcategory': 'Corn'
        }
    }
]

我正在使用Lodash,这就是我提出的,但有些东西告诉我有更简洁的方法吗?

filteredSum: function () {
    return _(this.sales).groupBy('product.id').map(function (sales) {
        return {
            'quantity': _.sumBy(sales, function(sale) { return Number(sale.quantity); }).toFixed(2),
            'amount': _.sumBy(sales, function(sale) { return Number(sale.amount); }),
            'product': {
                'category': _.head(sales).product.category,
                'subcategory': _.head(sales).product.subcategory
            }
        }
    }).value();
}

当然有更好的方法吗?

1 个答案:

答案 0 :(得分:3)

最简单的方法是使用productId作为主键的Object。然后只需使用reduce迭代您的数组。如果当前产品的productId已经存在,只需将其值与前一个值相加,否则将其添加到对象中。

const data = [
  {
    'quantity': 20,
    'amount': 40,
    'product': {
      'id': 1,
      'category': 'Chemical',
      'subcategory': 'Herbicide'
    }
  },
  {
    'quantity': 10,
    'amount': 70,
    'product': {
      'id': 1,
      'category': 'Chemical',
      'subcategory': 'Herbicide'
    }
  },
  {
    'quantity': 30,
    'amount': 60,
    'product': {
      'id': 2,
      'category': 'Seed',
      'subcategory': 'Corn'
    }
  }
];

const result = data.reduce((acc, curr) => {
  if (acc[curr.product.id]) {
    acc[curr.product.id].quantity += curr.quantity;
    acc[curr.product.id].amount += curr.amount;
  } else {
    acc[curr.product.id] = curr;
  }
  
  return acc;
}, {});

const formatedResult = Object.keys(result).map(entry => {
  return result[entry];
});

console.log(formatedResult);