代码之家  ›  专栏  ›  技术社区  ›  Lucas Constantino Silva

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

  •  1
  • Lucas Constantino Silva  · 技术社区  · 7 年前

    如何使用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 回复  |  直到 7 年前
        1
  •  2
  •   Bergi    7 年前

    你可以这样做:

    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>

    这也可以写得更简洁一些,如

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

    如果你想实现零积分,我想这也可以:

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

    虽然我觉得它不太可读。

    笔记

    这是一条单独的管道 as代码 但是 chain 应用于函数的工作方式如下 chain(f, g)(x) //~> f(g(x), x) . (从技术上讲,这不是事实,更像是 chain(f, g)(x) //~> f(g(x))(x) ,但通常与拉姆达相似。)因此,将有两个单独的值迭代,一个用于计算总数,另一个用于计算给定值和总数的每个百分比。当然,这在数学上是至关重要的。您不能计算和同时使用该和,但我不想在这里混淆单一管道的概念。