# JS :: Summing numbers over a range of lines (with Array.reduce)

If we want to sum numeric values over a range of lines or drafts, we can write a reusable sum function in terms of Array.reduce:

``````// sum :: [Num] -> Num
const sum = xs =>
xs.reduce((a, x) => a + x, 0);
``````

Starting with 0 as an accumulator seed value, it adds each current item x to the accumulator a, and returns the sum of the whole list.

So, if we have mapped each line in our draft to a corresponding number,

(for example the number of minutes expressed by a string like `2h 30m` at the end of the line)

``````draft.content
.split('\n')
.map(minsFromHMstring)
``````

where minsFromHMstring might be something like:

``````// minsFromHMstring :: String -> Int
const minsFromHMstring = s => {
const m = /\s*(\d+)h\s+(\d+)m\s*\$/.exec(s);
return Boolean(m) ? (
(60 * parseInt(m, 10)) + parseInt(m, 10)
) : 0;
};
``````

We can just apply sum to this list of numbers:

``````(() => {

// main :: () -> IO Int
const main = () => {

const intMins = sum(
draft.content
.split('\n')
.map(minsFromHMstring)
);

return (
intMins
);
};

// sum :: [Num] -> Num
const sum = xs =>
xs.reduce((a, x) => a + x, 0);

// minsFromHMstring :: String -> Int
const minsFromHMstring = s => {
const m = /\s*(\d+)h\s+(\d+)m\s*\$/.exec(s);
return Boolean(m) ? (
(60 * parseInt(m, 10)) + parseInt(m, 10)
) : 0;
};

return main();
})();
``````
1 Like
3 Likes

I find these interesting, but there I times I think I’ll just stick with:

``````let sum = 0;
for (var s in draft.content.split('\n')) {
const m = /\s*(\d+)h\s+(\d+)m\s*\$/.exec(s);
sum += m ? (60 * parseInt(m, 10)) + parseInt(m, 10) : 0;
}
``````

Sure – each approach is optimised for different things.

What I personally like about reduce is that it’s

• pre-built and pre tested
• takes care of the mechanics for us (no need to set up a loop), and
• returns a value without the need to depend on mutation and operators like += which need careful handling, and can often trip us up.

The advantage of just pasting and composing reusable functions like

``````const sum = xs => xs.reduce((a, x) => a + x, 0);
``````

Is, of course, that it spares us some of the tedium of endlessly reinventing (and re-testing) all our wheels : - )

1 Like

PS another balance is, of course, between:

• economy of ink (brevity of expressions)
• economy of scripter time ( less puzzled time later, tracking down a bug )

In that light, my preference is to waste less debugging time, and be more relaxed about using more ink.

For example:

Bracketing ternary expressions

Where you have the perfectly clear and functional

``````sum += m ? (60 * parseInt(m, 10)) + parseInt(m, 10) : 0
``````

I would tend to add parentheses, just because I have often found bugs that turned on what was (or wasn’t) included in the initial test section, for example.

``````sum += (m ? (60 * parseInt(m, 10)) + parseInt(m, 10) : 0)
``````

Explicit or implied coercion

The advantage of implied coercion is that we have to type less. For example your implied coercion of a Regex match (null | Array) to a Bool:

``````m ?
``````

Or the common coercion of numbers to strings.

Making coercions explicit, eg

``````Boolean(m) ?
``````

or

``````intMins.toString()
``````

Is technically redundant in many contexts, does waste ink, and looks more noisy, but it’s also a way of reducing time looking for bugs later on.

Undetected automatic type-coercions are quite a productive source of unexpected JS bugs. : -)

That’s why for example, I prefer to never use the slower `==` (equality test after automatic type conversion) and always use the faster `===` (direct equality test, without type conversion)

2 Likes