【问题标题】:What is the most concise way to use reduce() with the + operator?将 reduce() 与 + 运算符一起使用的最简洁方法是什么?
【发布时间】:2021-04-08 02:23:55
【问题描述】:

情况:我想用二进制加法调用reduce

理想的是简洁,语法优雅,即,

arr.reduce( + , 0 )

但这实际上并没有像写的那样工作。我在网上看到的例子往往更像

arr.reduce( (a, b) => a+b, 0 ).

这行得通,但感觉应该有一种更简单、更“优雅”的方式来做像二进制加法这样简单的事情。

问题:有没有什么方法可以避免定义一个完整的匿名函数来告诉reduce我想要二进制加法?

【问题讨论】:

  • 不,不可能,很遗憾。
  • 你能做的最好的就是写一个可以用作arr.reduce(binOp("+"), 0)的辅助函数
  • 只是为了好玩:你可以这样做:const ???? = (a, b) => a + b;,这样你就可以写:arr.reduce(????, 0)。 (它使用Lycian letter H 作为函数名,肯定会让每个读过你的代码的人感到困惑,包括未来的你!)

标签: javascript lambda functional-programming operators binary-operators


【解决方案1】:

如果您要多次使用 reduce,有一种更优雅的方式来使用它,尽管没有内置方式。 将此添加到代码的底部

function add(a, b){
  return total + num;
}

然后,当你想使用你的 reduce 函数时,添加这个

let i = arr.reduce(add)

【讨论】:

  • 好答案。我只是想补充一下,像这样的常用函数通常已经在 lodash 等 fp 库中定义。
  • 不要忘记以初始累加器值传递的0
  • 您的 add 函数返回语句看起来错误。你的意思是return a + b
【解决方案2】:

总之不,我不这么认为。

据我所知,运算符(作为表达式的一部分)不能用作函数参数,因为一旦定义它们就会被求值。

对于arr.reduce(+,0),运行时会尝试评估+,而不是将其传递给reduce。

相反,您需要一种将定义调用区分开来的方法,这正是您使用函数获得的语义。

【讨论】:

  • 是的,措辞不好。我试图修复
【解决方案3】:

这表明,尽管 JavaScript 可以启用函数式编程风格(在一定程度上),但 JavaScript 不是函数式语言。

我认为你所拥有的已经足够好了。在这一点上,你能做的最好的事情就是尽可能清楚地表达你的意图(当然是 YMMV):

const add = (a, b) => a + b;
const sum = (...xs) => xs.reduce(add, 0);

sum(40, 1, 1);
// 42

JavaScript 不是函数式语言?!

这当然只是我的看法,但与 Clojure 或 Haskell 等其他语言不同,在 JavaScript 中 + 不是函数而是运算符,这意味着您不能将其分配给变量或将其作为参数传递。

在 Haskell 中,您可以添加两个数字,如下所示:

40 + 2

+ 似乎是一个运算符,但它实际上是一个(中缀)函数,您可以将其作为参数传递并部分应用:

foldl (+) 0 [40, 1, 1]
-- 42

map (+ 10) [40, 1, 1]
-- [50, 11, 11]

在 Clojure 中,您可以添加两个数字,如下所示

(+ 40 2)
; 42

不过在 Clojure 中 + 实际上也是一个函数:

(reduce + 0 '(40 1 1))
; 42

但这不是必需的,因为 + 无论如何都可以处理数字列表:

(+ 40 1 1)
; 42
(+ 39 1 1 1)
; 42
(+ 38 1 1 1 1)
; 42

【讨论】:

    【解决方案4】:

    正如@superJumbo 所说,运算符不是javascript 中的函数。这是不幸的,因为你不能真正受益于像 haskell 这样的语言的表达能力。

    然而,javascript 开发人员推出了旨在带来这种表现力的库! RamdaSanctuary 就是很好的例子...

    const sum = R.reduce(R.add, 0);
    
    console.log(
      sum([1, 2, 3, 4, 5, 6, 7]),
    );
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js" integrity="sha512-rZHvUXcc1zWKsxm7rJ8lVQuIr1oOmm7cShlvpV0gWf0RvbcJN6x96al/Rp2L2BI4a4ZkT2/YfVe/8YvB2UHzQw==" crossorigin="anonymous"></script>

    或者,更简洁:

    console.log(
      R.sum([1, 2, 3, 4, 5, 6, 7]),
    );
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js" integrity="sha512-rZHvUXcc1zWKsxm7rJ8lVQuIr1oOmm7cShlvpV0gWf0RvbcJN6x96al/Rp2L2BI4a4ZkT2/YfVe/8YvB2UHzQw==" crossorigin="anonymous"></script>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多