Why Your Sorted List Is in the Wrong Order
Uppercase before lowercase, item10 before item2, and accents at the end. Sorting is doing what it was told — here is what it was told.
· 3 min read
Almost every surprising sort result comes from the same gap. A computer sorts by comparing the numeric codes behind characters. A person sorts by a set of cultural rules they were taught and have never had to state out loud. The two agree often enough that the disagreements look like bugs.
Uppercase before lowercase
In the character table every language inherited, uppercase A is 65 and lowercase a is 97. All twenty-six capitals come before any lowercase letter. A naive sort therefore produces Zebra before apple, which looks broken and is arithmetically correct.
by character code what a person expects
Apple Apple
Zebra apple
apple Banana
banana banana
ZebraThe fix is a case-insensitive comparison, which is what almost everyone actually wants from a visible list. Note that it makes the sort unstable between items differing only in case, so a tie-break is worth defining if the order has to be reproducible.
item10 before item2
Text comparison works character by character, left to right, and stops at the first difference. Comparing item10 with item2 reaches the digit 1 against the digit 2, finds 1 is smaller, and puts item10 first. It never gets far enough to notice these are numbers at all.
What people expect here is called natural sort: a comparison that recognises runs of digits and compares them numerically. It is not the default anywhere, because it is ambiguous the moment a string contains something that looks like a number but is not — a version, a date, a product code with leading zeros.
If you control how the values are generated, zero-padding sidesteps the whole problem: item002 and item010 sort correctly under plain text comparison, permanently and in every system that will ever touch them.
Digits, symbols and where they land
Digits sit below letters in the character table, so anything starting with a number sorts before everything alphabetic. Most punctuation sits below the digits, which is why a line beginning with a hyphen or a quotation mark ends up at the very top. Again, correct by the rules, and rarely what anyone wanted.
Accents, and why they go to the end
Accented characters live far above the plain Latin alphabet in the character table, so é sorts after z rather than beside e. Every language with accents has a rule for this, and the rules differ: in Spanish ñ is a separate letter following n, in Swedish å ä ö come after z, and in French accents are compared only when the base letters are otherwise identical.
There is no universal alphabetical order. There is only the order of a particular language, which is why the comparison has to be told which one.
This is what locale-aware collation is for. Every modern platform ships a comparator that takes a language and applies its actual rules — including case handling and, optionally, numeric ordering. It is slower than comparing codes, which matters for sorting a million rows and not at all for sorting a list a person will read.
The invisible causes
- Leading or trailing whitespace, which sorts below every printable character and pushes a line to the top.
- A non-breaking space pasted from a document, which looks identical to a space and has a different code entirely.
- Windows line endings leaving a stray carriage return at the end of every line.
- Two visually identical strings using different Unicode normalisations — one accented character versus a letter plus a combining mark.
When one line refuses to sort where it obviously belongs, the cause is nearly always one of these rather than the comparison. Trimming the input first removes most of them, and normalising the text removes the rest.
Frequently asked questions
- Why does my list put numbers before letters?
- Digits occupy lower positions than letters in the underlying character table, so any line starting with a digit sorts before any line starting with a letter. That is the defined order, not a fault in the sort.
- How do I make item2 come before item10?
- Use a natural sort, which compares runs of digits as numbers rather than as characters. If you control how the values are created, zero-padding them to a fixed width achieves the same result in every system without special handling.
- Why do two identical-looking lines not sort together?
- They are almost certainly not identical. Trailing whitespace, a non-breaking space, a stray carriage return, or a different Unicode normalisation of the same accented letter all produce lines that look the same and compare differently.
Related reading
- 3 min read
camelCase, snake_case or kebab-case: Which Goes Where
Naming conventions are not preferences. Each language and format has one the tooling expects, and going against it costs more than it looks.
- 3 min read
encodeURI or encodeURIComponent? One Rule That Works
The two differ by eleven characters, and picking wrong either breaks the URL or corrupts the value. Here is the rule, and the plus-sign trap.
- 3 min read
Favicon Sizes You Actually Need
Generators offer dozens of sizes and almost nobody needs them all. Which files earn their place, which link tags matter, and why 16px decides it.
- 3 min read
How Much Can You Compress an Image Before It Shows?
The quality number is not a percentage of anything. What the artefacts look like, where they appear first, and how to find your own limit.