[英]Several small reduce vs one big forEach?
使用reduce
:
addSales(sales: Sale[]) {
this.total += sales.reduce((ac, sale) => ac + sale.total, 0);
this.tax += sales.reduce((ac, sale) => ac + sale.tax, 0);
this.discount += sales.reduce((ac, sale) => ac + sale.discount, 0);
this.qty += sales.reduce((ac, sale) => ac + sale.qty, 0);
}
使用.forEach
addSales(sales: Sale[]) {
sales.forEach(sale => {
this.total += sale.total;
this.tax += sale.tax;
this.discount += sale.discount;
this.qty += sale.qty;
});
}
在这里使用.forEach
似乎更具可读性,也许在性能上更好,因为它只会循环一次。
但是从长远来看,它是否会使模块化程度降低? 我的代码的某些部分以较小的.forEach
块.forEach
,但是随着时间的.forEach
,它的大小增加了,并且由于相互“捆绑”而难以重构。
您可以分享您的经验吗?
理查德的回答很好,但是如果您想坚持使用reduce
来避免局部突变,则可以这样做,同时仍然只访问每个对象一次。 实际上, reduce
优点在于我们可以将数组转换为所需的任意值,因此让我们玩得开心
export function tallySales(sales: Sale[]) {
return sales.reduce((ac, {total, tax, discount, qty}) => ({
total: ac.total + total,
tax: ac.tax + tax,
discount: ac.discount + discount,
qty: ac.qty + qty
}), {total: 0, tax: 0, discount: 0, qty: 0});
关于特定的模块化问题,使用上述样式绝不是模块化的,但是它确实鼓励我们编写更多可测试的代码,因为我们是根据函数的输入和输出来表达事物的。 上面的函数可以很容易地进行测试,而使类实例的动态绑定发生变化的命令式版本要测试起来更加复杂,尽管在这种情况下并不一定要测试太多。
有趣的是,它根本就不是使用reduce
forEach
。 实际上,上述函数可以用forEach
编写,并且与reduce
一样,它是可维护和可测试的,并且是模块化的。 这与使用reduce
如何使我们在用值表示接口的思想框架中而不是修改与许多生产者和消费者相关的状态以隐式地使程序前进有关。
在这里使用forEach
没什么错,并且它肯定比进行多次调用来reduce
效率更高(尽管可以忽略不计,除非sales
包含很大的数量)。 正如您提到的,它也更具可读性
你可以通过this
来reduce
作为种子,做所有的变化在一起,但因为代码是变异的情况下并没有太多通过使用功能更强大的方式来获得。
我会坚持forEach。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.