如何处理子操作并保持与Ramda的功能?

时间:2018-02-19 23:25:22

标签: functional-programming ramda.js

如何使用ramda解决单个处理管道中的子操作?假设我有一个数字数组,并希望返回一个百分比数组,每个数字在总数中等效:

const values = [1, 5, 8, 2, 5]

// 1 - Get total: 1 + 5 + 8 + 2 + 5 = 21
// 2 - Return percentages of each item:
//
// 2.1 - 1: (1 * 100) / 21 = 4.761904762%
// 2.2 - 5: (5 * 100) / 21 = 23.80952381%
// 2.3 - 8: (5 * 100) / 21 = 38.095238095%
// 2.4 - 2: (5 * 100) / 21 = 9.523809524
// 2.5 - 5: (5 * 100) / 21 = 23.80952381%
percents(values) // [4.76, 23,80, 9.52, 23,80]

我可以使用单个Ramda管道/组合物来解决这个问题吗?

1 个答案:

答案 0 :(得分:2)

嗯,你可以这样做:



const {compose, map, multiply, chain, flip, divide, sum} = R

const percentages = chain(tot => values => map(val =>  100 * val / tot, values), sum)
console.log(percentages([1, 5, 8, 2, 5]))

<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>
&#13;
&#13;
&#13;

这也可以稍微紧凑地写成

const percentages = chain(compose(map, tot => val => 100 * val / tot), sum)

如果你想尝试点免费,我想这也可以:

const percentages = compose(map(multiply(100)), chain(compose(map, flip(divide)), sum))

虽然我发现它的可读性较差。

注意

这是一个单独的管道作为代码,但应用于函数的chain的工作方式类似于chain(f, g)(x) //~> f(g(x), x)。 (从技术上讲,这不是真的,它更像chain(f, g)(x) //~> f(g(x))(x),但通常与Ramda一样,它们相似。)所以你的值会有两次单独的迭代,一次到计算总数,并计算给定值和总数的每个百分比。当然,这在数学上是必不可少的。您无法计算总和并同时使用该总和,但我不希望单个管道的概念在这里混淆。