← All Tools

Natural Sort: Why item2 Should Come Before item10

Guide · Last verified Aug 27, 2026

You've probably sorted a file list or a table and ended up with a jumbled order like "item1, item10, item2, item20, item3." Nothing's broken — the default sort method (lexicographic sort) is designed to behave exactly that way. This guide breaks down why that happens, and how "natural sort" — the approach that sorts things in the order humans actually expect — solves the problem internally.

1. Lexicographic sort doesn't see numbers as numbers

A computer's default string sort compares characters one at a time, left to right. Comparing "item10" and "item2," the first four characters "item" match, and at the fifth character it compares '1' against '2'. Since '1' has a lower code point than '2' in Unicode, the sort algorithm concludes "item10" comes before "item2" without ever looking at the leftover '0'. In other words, it never treats "10" as the quantity ten — it just treats it as a string where '1' happens to be followed by '0'. That's the root cause of why this doesn't look like natural-language order.

2. Natural sort's fix: split the string into chunks

Instead of comparing a string character by character all the way through, natural sort first splits it into "runs of digits" and "runs of non-digits." For example, the string "item10-v2" gets split by regex into a chunk array that alternates between numeric and non-numeric, like ["item", "10", "-v", "2"]. It then compares the chunks at matching positions — if both chunks are numeric, it compares them as integers converted via parseInt rather than as strings; if either is non-numeric, it falls back to ordinary string comparison (localeCompare, depending on the case-sensitivity option). This way, comparing "10" and "2" compares them by their actual magnitude — ten versus two — so 2 correctly sorts before 10, matching what a human would expect.

3. Confirmed in the actual tool's code

Opening the source of the Text Line Sorter tool, the naturalCompare function that runs when you pick the "Numeric" option is implemented exactly this way. It splits a string into numeric and non-numeric chunks using the regex /(\d+|\D+)/g, then compares each line's chunks at the same position, in order. When both chunks match a pure-digit pattern (/^\d+$/), it converts them to integers and compares magnitude; otherwise it falls back to string comparison, respecting the case-sensitivity option. This tool clearly separates ordinary sort (A→Z, Z→A) from natural sort (Numeric) as distinct buttons, so when you're sorting text that mixes filenames or item numbers, you need to explicitly pick "Numeric" mode to get the result you expect. The A→Z mode is pure lexicographic comparison (localeCompare), and produces a different result from natural sort.

Practical example: Feed in "item1, item2, item3, item10, item20" in random order and sort it with each mode — the results diverge as shown below.
Sort methodResult order
A → Z (lexicographic)item1, item10, item2, item20, item3
Numeric (natural sort)item1, item2, item3, item10, item20

Same data, same tool — a single option flips the result entirely. If you paste a sorted list into a document without double-checking, it's easy to end up with items out of order, so it's worth making a habit of confirming the "Numeric" option is on whenever your text contains numbers.

4. Natural sort isn't a cure-all either

Natural sort is strong at comparing integer magnitudes, but applying it as-is to version numbers with decimal points can actually be confusing. Take "1.9" and "1.10" as software version numbers — 1.10 is the newer version, but since the natural sort algorithm treats "." as a non-numeric chunk and compares "9" and "10" as two independent numeric chunks, it actually produces exactly the correct order: 1.9 < 1.10. On the other hand, something like "v1.02" with a leading zero is handled fine too, since the leading-zero information disappears the moment it's converted to an integer. That said, expressions where a number is directly followed by a unit or particle (in Korean, something like "10개," "2개") do get their chunks split correctly, but natural sort is purely a sorting rule — it doesn't understand morphology or word meaning, so it has real limits when it comes to reflecting contextual meaning.

FAQ

Q. Which should be the default — lexicographic or natural sort?

If numbers are mixed into your text and you want their magnitude reflected in the order, use natural sort (Numeric). If you need pure character-code-based ordering — for example, to reproduce a programming language's default sort behavior — use lexicographic sort. It depends on the use case, and both are "correct" in different situations.

Q. Is Excel or a file explorer's sort based on the same principle?

Yes. Most OS file explorers (Windows Explorer, macOS Finder) display filenames using natural sort, so "file2" comes before "file10." But a programming language's default array sort function or a database's string column sort is usually lexicographic by default.

Q. Are negative numbers and decimals handled correctly by natural sort?

Regex-based natural sort only groups consecutive digit characters (0-9) into a single chunk, so a minus sign (-) or decimal point (.) gets split off as its own non-numeric chunk. That means "-5" isn't treated as a single signed integer — it's split into "-" and "5" and compared that way, so lists containing negative numbers can sort differently than you'd expect.

Q. Does the case-sensitivity option apply to natural sort too?

Yes. When a chunk isn't numeric, how it's compared depends on the case-sensitivity option. With the option off, "Item2" and "item2" are treated as having equal priority; with it on, uppercase and lowercase are treated as distinct characters and compared accordingly.