Find the bug · Easy

Fix the Median (JavaScript Sort)

Easy Find the bug Most asked

median(nums) returns the median of a non-empty array of numbers: the middle value after sorting, or the average of the two middle values when the length is even.

It works in every test with single-digit numbers and gives nonsense for real data. Find the bug and fix it.

Example 1

Input: nums = [3, 1, 2]
Output: 2

Example 2

Input: nums = [10, 9, 2]
Output: 9
Explanation: The buggy version returns 2.

The buggy code

function median(nums) {
  const sorted = [...nums].sort();
  const mid = Math.floor(sorted.length / 2);
  return sorted.length % 2 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;
}

Hints

Hint 1

What does [10, 9, 2].sort() return in JavaScript?

Hint 2

How does Array.prototype.sort compare elements when you pass no comparator?

Find and fix the bug

Loading the editor… (JavaScript is required to run code in your browser.)

Solution and explanation

Show the bug and the fix

Time O(n log n) · Space O(n)

The bug: without a comparator, sort() converts the elements to strings and sorts them in UTF-16 order, so "10" < "2" < "9" and "-1" < "-5". Small single-digit tests happen to sort correctly, which is why the bug slips through.

The fix: pass a numeric comparator: sort((a, b) => a - b). Sort a copy ([...nums] or toSorted) so the caller's array is not reordered.

Fixed version

function median(nums) {
  const sorted = [...nums].sort((a, b) => a - b); // numeric, not string, order
  const mid = Math.floor(sorted.length / 2);
  return sorted.length % 2 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;
}

Common mistakes

  • sort((a, b) => a > b) returns a boolean, not a number: inconsistent results across engines.