简体   繁体   中英

What is the most concise way to use reduce() with the + operator?

Situation: I want to call reduce using binary addition.

The ideal would be something concise, with elegant syntax, namely,

arr.reduce( +, 0 )

but this doesn't actually work as written. The examples I've seen online tend to be more like

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

This works, but it feels like there ought to be an easier, more "elegant" way of doing something as simple as binary addition.

Question: Is there some way to avoid defining an entire anonymous function just to tell reduce that I want binary addition?

This shows that even though JavaScript can enable a functional programming style (to a certain extent), JavaScript isn't a functional language.

I think what you have is good enough already. At this point the best you can do is try expressing your intent as clearly as possible (but of course YMMV):

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

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

JavaScript isn't a functional language?!

Well that's just my opinion of course but unlike other languages such as Clojure or Haskell, in JavaScript + isn't a function but an operator meaning that you cannot assign it to a variable or pass it as a parameter.

In Haskell you can add two numbers as follow:

40 + 2

It may seem that + is an operator but it is actually an (infix) function that you can pass as a parameter and partially apply:

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

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

In Clojure you can add two numbers as follow

(+ 40 2)
; 42

However in Clojure too + is actually a function:

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

However this isn't necessary as + works with a list of numbers anyway:

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

There is a more elegant way to use reduce if you are going to use it multiple times although there is no builtin way. Add this to the bottom of your code

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

Then, when you want to use your reduce function add this

let i = arr.reduce(add)

In short no, I don't think so.

As far as I know operators (being part of expressions) can't be used as function arguments because as soon as they're defined they're evaluated.

In the case of arr.reduce(+,0) , the runtime would try evaluate + instead of pass it to reduce.

Instead you want a way to tease apart definition from invocation , which are exactly the semantics you get with functions.

As @superJumbo said, operators are not functions in javascript. This is unfortunate because you can't really benefit the expressiveness of languages like haskell for instance.

However, javascript developers came out with libraries that aim to bring such expressiveness over! Ramda and Sanctuary are brilliant examples...

 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>

or, even more succintly:

 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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM