# Moving Average in Lodash

## From OO to Clojure Workshop!

Watch my free workshop to help you learn Clojure faster and shift your paradigm to functional.

Let's write a Moving Average function in JavaScript with Lodash.

But first, we'll review the regular average function. How does that look in JavaScript without Lodash?

```
function average(numbers) {
let sum = 0;
for (let i = 0; i < numbers.length; i++) sum += numbers[i];
return sum / (numbers.length || 1);
}
```

The only tricky thing is that we can't divide by zero, so we are using
the fact that `0`

is falsey to default `numbers.length`

to `1`

. In that
case, we'll just return 0. Not technically correct but a decent
compromise.

But let's turn this into a functional style. We're iterating through a
list and aggregating a result. That's a good job for `reduce`

.

```
function average(numbers) {
return _.reduce(numbers, (a, b) => a + b, 0) / (numbers.length || 1);
}
```

Very nice! Calling `reduce`

with `+`

and `0`

could be called `sum`

.
Let's refactor:

```
function sum(numbers) {
return _.reduce(numbers, (a, b) => a + b, 0);
}
function average(numbers) {
return sum(numbers) / (numbers.length || 1);
}
```

Now that's declarative! It almost reads like the English-language definition for average.

Now let's tackle the Moving Average. Given a list of numbers, you take a "window" around each number and calculate the average of the numbers in that window.

```
function moving_average(numbers) {
return _.chain(numbers).map(window).map(average).value();
}
```

We can read it like this: for each `number`

in `numbers`

, create a
window, average the window, and return the list of averages. We have the
function `average`

above. But what about `window`

?

```
function window(_number, index, array) {
return _.slice(
array,
Math.max(0, index - 3),
Math.min(array.length, index + 3)
);
}
```

Maybe that one-liner is hard to read. We'll give the parts some names:

```
function window(_number, index, array) {
const start = Math.max(0, index - 3);
const end = Math.min(array.length, index + 3);
return _.slice(array, start, end);
}
```

Let's see it all together:

```
function sum(numbers) {
return _.reduce(numbers, (a, b) => a + b, 0);
}
function average(numbers) {
return sum(numbers) / (numbers.length || 1);
}
function window(_number, index, array) {
const start = Math.max(0, index - 3);
const end = Math.min(array.length, index + 3);
return _.slice(array, start, end);
}
function moving_average(numbers) {
return _.chain(numbers).map(window).map(average).value();
}
```

Okay! That works. But now I want to be able to change the window. Right now, the window is 6 elements wide. Our boss is asking if we can change it. And if we need to change it once, we probably will need to do so again in the future. Let's anticipate that and make window more flexible:

```
function make_window(before, after) {
return function (_number, index, array) {
const start = Math.max(0, index - before);
const end = Math.min(array.length, index + after + 1);
return _.slice(array, start, end);
};
}
```

I changed it slightly: notice that I add `index+ after + 1`

, where
before there was no `+ 1`

. It just seems to make more sense with the
names `before`

and `after`

.

Now how does `moving_average`

look?

```
function moving_average(numbers) {
return _.chain(numbers).map(make_window(3, 2)).map(average).value();
}
```

Or we can pass the arguments in:

```
function moving_average(before, after, numbers) {
return _.chain(numbers).map(make_window(before, after)).map(average).value();
}
```