# Calculate median in real-time using JavaScript

Let's assume that a customer is spending money daily and we want to calculate the median of the expenses for the last 5 days.

For the first 4 days, we don't have enough data to compute, so we will begin to calculate the median at day number 5.

5th day:

```javascript```let expenses = [10, 20, 30, 50, 30];
-------------------
last 5 days expenses

let sorted   = [10, 20, 30, 30, 50];
---------+---------
median
``````

6th day:

```javascript```let expenses = [10, 20, 30, 50, 30, 70];
-------------------
last 5 days expenses

let sorted   = [20, 30, 30, 50, 70];
---------+---------
median
``````

7th day:

```javascript```let expenses = [10, 20, 30, 50, 30, 70, 80];
-------------------
last 5 days expenses

let sorted   = [30, 30, 50, 70, 80];
---------+---------
median
``````

As you can see, there are some patterns as days pass by:

1. Sorted has a constant number of items
2. Median is always at the same position
3. The next item to go away from `sorted` was the first to entry

## Setting initial parameters

Let's define a customer object taking into account the previous conditions. `customer.sorted` counts the frequency of the expenses, `customer.median` has the value of the median, and `customer.nextItemsToRemove` is a FIFO array of expenses.

```javascript```let customer = {

sorted: {
'10': 1,
'20': 1,
'30': 2,
'50': 1
},
median: 30,
nextItemsToRemove: [10, 20, 30, 50, 30]

}
``````

## Final algorithm

We need to update customer's properties on the go. Let's assume that we are on the 6th day.

As a new day has passed by:

1. Remove an item
3. Recalculate the median
```javascript```
// 1. Get item to remove
let itemToRemove = customer.nextItemsToRemove[0];

// 1a. Remove it from sorted object
if(customer.sorted[itemToRemove] > 1) customer.sorted[itemToRemove] --;
else                                  delete customer.sorted[itemToRemove];

// 1b. Remove item from nextItemsToRemove
customer.nextItemsToRemove = customer.nextItemsToRemove.slice(1);

// 2. Add new item to object
let newItem = expenses[5];

// 2a. Add it to sorted object
if(customer.sorted[newItem] > 0) customer.sorted[itemToRemove] ++;
else                             customer.sorted[itemToRemove] = 1;

// 2b. Add item to nextItemsToRemove
customer.nextItemsToRemove.push(newItem);

// 3. Recalculate median
customer.median = median(customer.sorted);

``````

Defining median function:

```javascript```const median = (object) => {

// Median will always be in the 3rd position
let position = 3;

// How many times the customer has spent 10, 20, 30, 50
let expenses  = Object.keys(object);
let frequency = Object.values(object);

for(let index = 0, sum = 0; index < expenses.length; index ++){

// We sum the elements in the array
sum = sum + expenses[index];

// Until we arrive to position 3
if(sum >= position){
customer.median = frequency[index];
break;
}

}

}
``````

The algorithm is valid for day 7th, 8th, 9th, and so forth.

Please, take into account that this is an oversimplification of the problem to get a general idea on how to calculate a moving median on the go. For example, I have assumed that the number of items to calculate the median was odd, but feel free to rethink the example if the number of items was even.

Hi, I'm Erik, an engineer from Barcelona. If you like the post or have any comments, say hi.