Joe*_*Joe 0 functional-programming pointfree ramda.js
假设我要计算平均费用:
const products = [
{
cost: 300
},
{
cost: 700
}
];
Run Code Online (Sandbox Code Playgroud)
因此,首先选择成本属性,对其进行汇总,然后除以项目的nr个。
const calcualteAveragePrice = R.pipe(
R.map(R.prop('cost') // [300, 700]
R.sum, // 1000
R.divide(??) // How do I divide with the number of items here??
)
Run Code Online (Sandbox Code Playgroud)
在最后一步中,我需要除以项目数。由于它是免费的,所以我不能arr.length
。
Ramda确实具有一个mean
功能(以及一个功能median
)。因此,这将使您的解决方案相当简单:
const calculateAveragePrice = compose (mean, pluck( 'cost'))
const products = [{cost: 300}, {cost: 700}]
console .log (
calculateAveragePrice(products)
)
Run Code Online (Sandbox Code Playgroud)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
<script>const {compose, mean, pluck} = R </script>
Run Code Online (Sandbox Code Playgroud)
或者,当然可以写pipe (pluck('cost'), mean)
。我更喜欢compose
单线,以及pipe
其他任何东西,但这只是个口味问题。
但是,如果您不知道Ramda提供了此功能,则可以使用以下代码编写自己的无点average
函数converge
:
const average = converge(divide, [sum, length])
Run Code Online (Sandbox Code Playgroud)
converge
及其表亲useWith
旨在简化编写无点代码版本的过程。我总是警告说,无分制本身很少是目标。仅当它用于提高代码的可读性时才有用。双方converge
并useWith
往往在这一点上值得商榷。FP世界中还有一个更标准的替代方法:function lift
:
const average = lift (divide) (sum, length)
Run Code Online (Sandbox Code Playgroud)
lift
将接受某些类型的值的函数转换为接受那些值的容器的函数。并且由于可以将返回给定类型的值的函数视为一个容器(如有必要,lift (f) (g, h)
可以斜视),因此等效于(x) => f (g (x), h (x))
。(有关SO问题的更多信息,Ramda.js中的“抬头”无法解决)。
converge
稍微灵活一些,但我会尽可能使用lift
。感觉比较标准。