localeCompare not detecting whole number when sorting

Stefan Bogdanescu

Founder & Senior Architect · 2026-06-29

Laravel Company

Fixing Sorting Nightmares: Why localeCompare Fails with Whole Numbers in JavaScript

As developers, we often deal with data manipulation, especially when presenting information in tables. A common task is sorting this data. When using JavaScript and libraries like jQuery, we frequently turn to string comparison methods like localeCompare() to sort text fields. However, when dealing specifically with whole numbers, these methods introduce subtle but critical errors.

This post will dive into why your current implementation fails to sort numerical data correctly and provide a robust, developer-approved solution.

The Pitfall of Lexicographical Sorting

You've encountered a classic issue: sorting numbers as strings results in lexicographical (alphabetical) sorting rather than numerical sorting. Let’s examine why your original approach using localeCompare() fails for sequences like [1, 10, 2].

When you convert these numbers to strings and compare them alphabetically:

  • '10' comes before '2' because the comparison starts with the first character: '1' is compared to '2'. Since '1' precedes '2', the string '10' is incorrectly placed before '2'.
  • Similarly, in a list like [1, 10, 12], lexicographically, '10' comes before '12' if you don't account for the length difference properly in a standard sort context, or it messes up the numeric sequence entirely.

The function of localeCompare() is to compare strings based on linguistic rules, which is excellent for sorting localized text (handling accents, letter order, etc.). However, when applied directly to string representations of numbers, it treats them purely as character sequences, ignoring their inherent mathematical value.

The Correct Approach: Explicit Numerical Comparison

To correctly sort numerical data, you must explicitly convert the values being compared into actual numbers before performing the comparison operation. This shifts the sorting logic from linguistic rules (string comparison) to mathematical rules (numerical magnitude).

Instead of relying on localeCompare(), which is designed for strings, we should use standard subtraction operators (<, >, ===) within the array sort function. This method is faster, clearer, and mathematically sound.

Revised Sorting Logic Example

We will modify your sorting function to extract the values, convert them to integers, and then compare them directly.

Here is how you can rewrite your sorting logic for numerical columns:

function sortTableNumerically(table, column, order) {
    var tbody = table.find('tbody');

    // Get all rows in the table body
    var rows = tbody.find('tr');

    rows.sort(function (a, b) {
        // Extract the text content from the specific column for rows a and b
        var valA = $('td:eq(' + column + ')', a).text();
        var valB = $('td:eq(' + column + ')', b).text();

        // *** The critical change: Convert to Number for sorting ***
        var numA = parseInt(valA, 10);
        var numB = parseInt(valB, 10);

        if (order === 'asc') {
            return numA - numB; // Ascending order (smaller number comes first)
        } else {
            return numB - numA; // Descending order (larger number comes first)
        }
    }).appendTo(tbody); 
}

Explanation of the Fix

  1. Extraction: We still extract the text content using jQuery selectors, but we immediately wrap it in parseInt(..., 10) to convert the string representation into a base-10 integer. This ensures that '10' becomes the number 10, and '2' becomes the number 2.
  2. Comparison: We use the subtraction trick: numA - numB.
    • If numA is smaller than numB, the result is negative, placing a before b (ascending).
    • If numA is larger than numB, the result is positive, placing b before a (descending).

This method guarantees that the sort order reflects true numerical magnitude, solving the issue entirely. This principle of efficient data handling and structuring is vital when dealing with complex datasets, much like managing data structures in frameworks such as those found within Laravel applications where performance matters significantly.

Conclusion

When sorting numbers in front-end JavaScript, always prioritize mathematical operations over string comparison functions like localeCompare(). While these methods are powerful for linguistic sorting, they fail when the underlying requirement is mathematical ordering. By explicitly casting your values to integers and using subtraction for comparison, you ensure your table data is sorted accurately, providing a solid foundation for any data-driven application you build.