DISCLAIMER: I don't think this is actually an "answer" answer. Please consider it as a side note, because your code generally looks good to me. I also admit, this answer is highly subjective compared to other my answers.. My purpose here is to provide a point of view rather than persuade that something needs to be fixed in the original code.
[Non-functional] alternative
In a real-life scenario, if num
input was huge, you might not be able to create a range array via new Array(num)
.
Number.MAX_VALUE
// ---> 1.7976931348623157e+308
new Array(Number.MAX_VALUE)
// VM234:1 Uncaught RangeError: Invalid array length
// at <anonymous>:1:1
Chrome:
Instead of that you could rewrite your range function as a generator function (at a "cost" of it not being an arrow function anymore):
function* range(num) { for (let counter = 1; counter <= num; counter++) yield counter; }
Unfortunately, this is also less functional on its own (notice that the code uses a let
variable...). Worse than that, you can only
- either manually iterate over it via
IterableIterator<>
interface (requires a variable);
- or use
for (let _ of range(Integer.MAX_VALUE) { ... }
which isn't looking functional;
- or try materialize it into an array via spread operator
[...range(Integer.MAX_VALUE)]
(which will not work, for the same exact reason I'm mentioning the generator function).
I wish there was a commonly known first-class concept of a Range in JavaScript...
Naming Things
The only thing that pokes my eyes is variable naming. IMHO, you can do better than acc
, val
, or i
. For example, the following is more readable, since real words are being used and the function is more explanatory.
const range = mapFunction =>
rangeLength =>
Array.from(new Array(rangeLength), mapFunction);
and
const summer = (subTotal, currentNumber) => subTotal + currentNumber;
summer
is better than sum
because a) sum
as a word denotes the result of summation rather than something that encapsulates the summation logic; b) reads better in the usage. In fact, you can even write const sum = someArray.reduce(summer)
, or if you prefer better consumer readability over function name -- const sum = someArray.reduce(withSummer)
.
I know, these are tiny details, but for the reader they make a difference. Once mentioned it in another answer already -- I've witnessed a situation where in an inline function a developer interpreted acc
as account
. Silly? Yeah, but who cares when one needs to work on Friday evening to fix a bug?