DEV Community

ValPetal Tech Labs
ValPetal Tech Labs

Posted on

Question of the Day #6 [Talk::Overflow]

This post explains a quiz originally shared as a LinkedIn poll.

πŸ”Ή The Question

const scores = [8, 80, 9, 100, 15];
scores.sort();
console.log(scores);
console.log(scores[0] < scores[4]);
Enter fullscreen mode Exit fullscreen mode

Hint: Consider how sort() compares values when no comparator function is provided.

πŸ”Ή Solution

Correct Answer: B) [100, 15, 8, 80, 9] and false

The output is:

  • [100, 15, 8, 80, 9]
  • false

🧠 How this works

This is one of JavaScript's most counterintuitive behaviors. When you call Array.prototype.sort() without a comparator function, all elements are converted to strings and sorted lexicographically (dictionary order), not numerically.

Lexicographic comparison works character by character from left to right:

  • '100' comes before '15' because '1' equals '1', but '0' < '5'
  • '8' comes before '80' and '9' because '8' < '9' in Unicode
  • '80' comes before '9' because '8' < '9'

The sort produces [100, 15, 8, 80, 9] β€” completely wrong for numeric ordering!

For the second output: scores[0] is 100 and scores[4] is 9. The comparison 100 < 9 is a numeric comparison (both values are numbers), which correctly evaluates to false.

The irony: The "sorted" array has its largest element first and a smaller element last, yet scores[0] < scores[4] returns false because numeric comparison works correctly β€” it's only the sort that's broken.

πŸ” Line-by-line explanation

  1. const scores = [8, 80, 9, 100, 15] β€” creates an array of numbers

  2. scores.sort() β€” sorts in place using string comparison:

    • Each number is converted to a string: ['8', '80', '9', '100', '15']
    • Strings are compared character by character (Unicode code points)
    • '1' (code 49) < '8' (code 56) < '9' (code 57)
    • Result: ['100', '15', '8', '80', '9'] β†’ converted back: [100, 15, 8, 80, 9]
  3. console.log(scores) β†’ [100, 15, 8, 80, 9]

  4. console.log(scores[0] < scores[4]) β†’ 100 < 9 β†’ false

The misleading part: Developers expect sort() to "just work" on numbers like it does in most other languages. JavaScript's design choice to stringify first makes sense for mixed-type arrays but creates this gotcha for numeric arrays.

πŸ”Ή The Fix

Always provide a comparator for numeric sorting:

// Ascending order
scores.sort((a, b) => a - b);
// Result: [8, 9, 15, 80, 100]

// Descending order
scores.sort((a, b) => b - a);
// Result: [100, 80, 15, 9, 8]
Enter fullscreen mode Exit fullscreen mode

πŸ”Ή Key Takeaways

  • Array.sort() without arguments converts elements to strings and sorts lexicographically
  • This affects all non-string types: numbers, dates, booleans, objects (which become '[object Object]')
  • Always provide a comparator function for numeric sorting: (a, b) => a - b
  • sort() mutates the original arrayβ€”it doesn't return a new one
  • This is one of JavaScript's most common production bugs, especially when code works in testing with small sample data

Top comments (0)