Index
Overview


The mode is the number which appears most often.

Though mode had less value from a scoring perspective, it can have signficant bang for the buck on the learning end.

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.

We check each group (i.e. a "run" of equal values).

If we find a larger group, we have a new mode
Given [10, 20, 20, 30]
best = []
bestCount = 0

first group (10) has count of 1
1 > 0, so we have new best
	best = [10]
	bestCount = 1

next group (20) has count of 2
2 > 1, so we have new best
	best = [20]
	bestCount = 2

next group (30) has count of 1
1 < 2, so no action
Here we handle the case where we have a "tie". In other words, two groups have the same size.

In this case, we append the matching group to best.
Given [10, 20]
best = []
bestCount = 0

first group (10) has count of 1
1 > 0, so we have new best
	best = [10]
	bestCount = 1

next group (20) has count of 1
1 == 1, so we have another best which we append to best
	best = [10, 20]


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'.
testModeOneResult() {
	//Two "30" elements
	const unit = new Stats([40, 10, 30, 20, 30]);
	this.assertEquals([30], unit.mode());
}

testModeTwoResults() {
	//Two "10" elements, and two "30" elements
	const unit = new Stats([10, 40, 10, 30, 20, 30]);
	this.assertEquals([10, 30], unit.mode().sort());
}

testModeUniqueValues() {
	const unit = [20, 10, 30];
	//If all elements are unique (no duplicates) then result incudes all elements.
	this.assertEquals(unit.sort(), unit.mode().sort());
}

testModeEmptyCase() {
	const unit = new Stats([]);
	assertEquals(null, unit.mode());
}



Conclusions From Manual Solutions


We can see we have two cases:

If the next group is longer than "best", we have a new best
If the next group is has the same length as "best", we append that group value to best.

Recipe


Our starting point (our given data).
nums -- list of numbers
Eliminate special cases right away. That simplifies the rest of the recipe.

If we pass this, we know nums has size >= 2.
let count = this.count()
if (count == 0) return null
if (count == 1) return this.nums
Preparing for our loop.

We sort the nums.

best (an array) is the our running result for mode which we'll return in the end.

current is the current mode we are looking at as we iterate (note that elems are sorted)
nums = this.nums
nums.sort()
len = nums.length
first = nums[0]
bestMode = []
bestCount = 0
groupMode = first
groupCount = 1
We loop starting at the second element.

We update the current mode (the one we are looking at) as we iterate.

Before we change to a new current (next new element value in sorted list) we check if current qualifies to be added to the best, and update best if it does.
let i = 1
While i <= len
	let next = i < len ? nums[i] : null
	if (next !== groupMode)
		if (groupCount === bestCount)
			bestMode.push(groupMode)
		else if (groupCount > bestCount)
			bestMode = [groupMode]
			bestCount = groupCount
		groupMode = next
		groupCount = 1
	else
		groupCount++
	i = i + 1
return bestMode
Recipes typically map nicely to code.

We just need to conform to the given coding language syntax.
let count = this.count();
if (count == 0) return null;
if (count == 1) return this.nums;
//...