induwara.lk
induwara.lkText · Utility

Sort Lines Alphabetically, Numerically, or by Length

Paste any list and sort the lines five ways — alphabetical, natural, numeric, by length, or random shuffle — ascending or descending, locale-aware, with stable ordering for duplicates. Every keystroke is processed in your browser, with two cross-checks running on the result.

By Induwara AshinsanaUpdated May 11, 2026
Sort linesStable, locale-aware, Unicode-safe
Runs entirely in your browser. Nothing is uploaded, logged, or stored.

Mode

Direction

Locale

Options

Mode applied
Alphabetical
Lines sorted
0
Input lines
0
Blanks removed
0
Enable Drop blanks to filter

Output length: 0 characters · 0 lines.

Sources: locale-aware comparison uses ECMA-402 Intl.Collator (Unicode Collation Algorithm, UTS #10). Numeric mode uses ECMA-262 parseFloat. Random mode uses Fisher-Yates with W3C Web Crypto unbiased indices. Full citations in the Sources section below.

How it works

Five sort modes share a common pipeline: split the input into lines, decorate each line with the value used for comparison (collation key, parsed number, code-point length, or a random uint32), sort the decorated pairs, then re-emit the original lines in the new order. The decorate-sort-undecorate pattern is the standard trick for keeping the comparator at O(n log n) calls when the key derivation is non-trivial.

  1. Split. The input is broken on the regular expression /\r?\n/, so LF (Unix/macOS), CRLF (Windows), and mixed inputs are all handled. A single trailing newline is detected and stripped before splitting, then re-appended at the end so a file like "a\nb\n" stays two lines, not three.
  2. Decorate. For alphabetical and natural mode each line is paired with an Intl.Collator key in the chosen locale — natural mode sets numeric: true so embedded digit runs sort as numbers. For numeric mode each line is parsed by a regex that accepts optional sign, integer and decimal parts, and scientific notation, then handed to parseFloat. For lengthmode the line's code-point count is computed by iterating the string with a for-of loop, so multi-byte characters count as one symbol — not the two UTF-16 code units String.length would report.
  3. Sort. JavaScript's Array.prototype.sort has been stable since ECMA-262 §23.1.3.31 was finalised in 2019. Stability matters when sorting by length or by a case-folded key — two lines that share a key keep their input order, so a sort never silently scrambles your data. Descending direction flips the comparator's sign rather than reversing the array, which preserves the stable-order guarantee within tie-groups.
  4. Random. Random mode skips the comparator entirely and runs a Fisher-Yates (Knuth) shuffle: walk the array right-to-left, swap each element with a uniformly-random earlier element. Indices are drawn from crypto.getRandomValues with rejection sampling, so the result is bias-free. Click Re-shuffle to draw a fresh permutation without re-typing.
  5. Cross-check. Every result runs two independent verifications. The first walks the output and confirms each adjacent pair is in the correct order under the chosen comparator — skipped for random mode. The second compares the input and output as multisets to confirm no line was added, lost, or duplicated. Both pass on every sort the algorithm performs correctly; if either fails, the badge on the calculator card flips red and the bug is yours to report.

A deliberate non-feature: Unicode normalisation is not applied. If two lines look identical but use different code-point sequences (precomposed é vs decomposed e + ◌́), they may sort to neighbouring positions but they remain distinct lines. That mirrors what every text editor shows you and avoids silently collapsing intentionally-different encodings — usually the wrong default for source code and data work.

Worked examples

Alphabetical, ascending

input = ["banana", "Apple", "cherry", "apple"]

  1. Split on /\r?\n/ → 4 lines
  2. Intl.Collator('en', sensitivity:'accent') keys = ["banana","apple","cherry","apple"]
  3. Stable sort asc → ["Apple","apple","banana","cherry"]
  4. Apple and apple tie under accent sensitivity — input order kept
  5. Output = "Apple\napple\nbanana\ncherry"

Numeric, ascending — non-numerics sink

input = ["10","2","apple","100","-1"]

  1. parseNumericLine → [10, 2, null, 100, -1]
  2. Bucket: numerics [10,2,100,-1] in input order; non-numerics ['apple']
  3. Sort numerics asc → [-1, 2, 10, 100]
  4. Concatenate non-numerics at the end (regardless of direction)
  5. Output = "-1\n2\n10\n100\napple"

Natural sort — file1, file2, file10

input = ["file10","file2","file1","FILE3"]

  1. Intl.Collator('en', numeric:true) treats digit runs as numbers
  2. Stable sort asc → ["file1","file2","FILE3","file10"]
  3. Accent-insensitive default folds the case of "FILE3" to "file3"
  4. Output = "file1\nfile2\nFILE3\nfile10"

By length, descending — code-point aware

input = ["ආයුබෝවන්","hi","hello","ක"]

  1. Code-point lengths = [8, 2, 5, 1]
  2. Stable sort desc → ['ආයුබෝවන්','hello','hi','ක']
  3. String.length on "ආයුබෝවන්" would report 8 UTF-16 units — same answer here, but code-point count is what users expect for Indic scripts
  4. Output = "ආයුබෝවන්\nhello\nhi\nක"

Frequently asked questions

Sources & references

Related tools

Rate this tool
Be the first to rate

Comments & feedback

Spotted a bug or want an improvement? Tell us — our team reviews every comment, and good ideas get built. Comments are public and anonymous.

Found an edge case, an unexpected order, or want a new mode?

Email me at [email protected] — most fixes ship within 24 hours.