Index
Overview


The median is the middle of a sorted list of numbers.

Though median had less value from a scoring perspective, it's bang for the buck from a learning perspective.

As always, the solutions shown are not the only solutions (there are many).

We'll use basic array operations for this solution, for learning.

Also see suggested approach....

Manual Solutions


This is often what we will do first when using a recipe approach

These old pencil-and-paper style manual solutions are often our best friends.

Most important, is that we pre-sort the array.

When the length of the list is odd, the median is simply the middle element.
Given [30, 10, 20]

//sort
sorted = [10, 20, 30]

middleIndex = sorted.length / 2 = 3/2 = 1.5
round down middleIndex = 1

median = sorted[middleIndex] = 20
Most important, is that we pre-sort the array.

When the length of the list is even, the median is simply the number between the two middle elements.
Given [30, 10, 40, 20]

//sort
sorted = [10, 20, 30, 40]

index2 = sorted.length/2 = 4/2 = 2
index1 = index2 - 1 = 2 - 1 = 1

n1 = sorted[index1] = 20
n2 = sorted[index2] = 30

median = (n1 + n2) / 2


Unit Tests


We'll take a test first approach.

Example Tests
Just this small group of tests covers a lot of the scenarios for 'mode'.
testMedianOddCase() {
	const unit = new Stats(30, 10, 20]);
	this.assertEquals(20, unit.median());
}

testMedianEvenCase() {
	const unit = new Stats([30, 10, 40, 20]);
	this.assertEquals(25, unit.median());
}

testMedianOneValue() {
	const unit = new Stats(200]);
	this.assertEquals(200, unit.median());
}

testMedianEvenCaseFloatingPointCenter() {
	const unit = new Stats([20, 15, 20, 15]);
	this.assertEquals(17.5, unit.median());
}

testMedianEmptyCase() {
	const unit = new Stats([]);
	this.assertEquals(null, unit.median());
}



Conclusions From Manual Solutions


We can split the solution in two (odd, even). Partitioning always simplifies the logic.

Recipe


Special Cases
Eliminate special cases right away. That simplifies the rest of the recipe.
let count = this.count()
if (count == 0) return null
Odd or Even
Many coding languages have a modulus (remainder operator) which is usually %.

Then, w can determine if a number is odd using:
(n % 2) == 1
if nums.length is odd
	call Recipe (Odd Length Case)
else
	call Recipe (Even Length Case)


Recipe (Odd Number of Elements)


NOTE WELL -- we would want to add this as a new method (named something like "medianForOddCount") and then call it from the "median" method.

Solving
We were able to basically just follow our manual solution here.

Note that "floor" or "truncate" is often the coding tool to round a number down (it will vary by language)

Something like this:
middleIndex = Math.round(middleIndex);
nums = this.nums
sorted = nums sorted
middleIndex = sorted.length / 2
middleIndex = middleIndex rounded down
median = sorted[middleIndex]
return median


Recipe (Even Number of Elements)


NOTE WELL -- we would want to add this as a new method (named something like "medianForEvenCount") and then call it from the "median" method.

Solving
We were able to basically just follow our manual solution here.
nums = this.nums
sorted = nums sorted
index2 = sorted.length / 2
index1 = index2 - 1
n1 = sorted[index1]
n2 = sorted[index2]
median = (n1 + n2) / 2
return median