Toolmingo
Guides6 min read

How to Sort Text Alphabetically (Lines, Lists, and Words)

Learn how to sort text alphabetically, numerically, or by length. Covers ascending and descending order, case sensitivity, locale-aware sorting, and code examples in JavaScript, Python, Go, and PHP.

How to Sort Text Alphabetically

Sorting a list of names, URLs, keywords, or log lines by hand is tedious and error-prone. Whether you need a quick alphabetical sort or a complex multi-key numeric sort, understanding how sorting works — and which tool to use — saves significant time.


What "Alphabetical Order" Actually Means

Alphabetical (lexicographic) order compares characters one by one using their code point values. In ASCII/Unicode:

  • digits 0–9 come before uppercase A–Z
  • uppercase A–Z comes before lowercase a–z
  • spaces and punctuation have their own positions

This means a naive sort produces results that can surprise you:

Input:           Naive sort (ASCII):
banana           Apple
Apple            banana
cherry           cherry

Apple sorts before banana because uppercase A (code point 65) is less than lowercase b (98).


Sort Modes You Need to Know

Mode What it does Example use case
Ascending A→Z Standard alphabetical Alphabetize a word list
Descending Z→A Reverse alphabetical Prioritize Z entries first
Case-insensitive Ignores upper/lower Mixed-case name lists
Numeric Sorts by embedded numbers Log files, version numbers
By length Shortest to longest Keyword research, CSS
Reverse lines Flips the order View log files bottom-up
Remove duplicates Unique lines only Dedup email lists

Case Sensitivity: The Most Common Trap

When you sort case-insensitively, apple, Apple, and APPLE are treated as equal. The stable sort keeps their original relative order.

Case-sensitive (default ASCII):

Apple
banana
cherry

Case-insensitive (natural):

Apple
banana
cherry

Same result here — but with a list like ["zoo", "Apple", "ant"]:

Case-sensitive:   Case-insensitive:
Apple             ant
ant               Apple
zoo               zoo

For most human-facing lists, case-insensitive sort is what you want.


Numeric Sort vs Lexicographic Sort

Sorting version numbers or file names lexicographically gives wrong results:

Lexicographic:    Numeric:
v10.0             v1.0
v1.0              v2.0
v2.0              v10.0

The number 10 sorts before 2 lexicographically because the character 1 < 2. Always use numeric sort when your lines contain numbers you care about ordering.


Algorithm: How Sorting Works

Most sort implementations use one of these algorithms:

Algorithm Time complexity Best for
Timsort (Python, Java) O(n log n) Real-world mixed data
Introsort (C++, Go) O(n log n) General purpose
Radix sort O(n·k) Fixed-length strings
Merge sort O(n log n) Stable, linked lists

For text sorting at any practical scale, the built-in sort of your language is sufficient — they are all O(n log n).


Code Examples

JavaScript

const lines = ["banana", "Apple", "cherry", "ant"];

// Case-insensitive ascending
const sorted = [...lines].sort((a, b) =>
  a.localeCompare(b, undefined, { sensitivity: "base" })
);
// ["ant", "Apple", "banana", "cherry"]

// Case-sensitive descending
const descending = [...lines].sort((a, b) => b.localeCompare(a));

// Numeric sort (for lines with numbers)
const versions = ["v10.0", "v2.0", "v1.0"];
const numericSorted = [...versions].sort((a, b) =>
  a.localeCompare(b, undefined, { numeric: true })
);
// ["v1.0", "v2.0", "v10.0"]

// Remove duplicates then sort
const unique = [...new Set(lines)].sort((a, b) =>
  a.localeCompare(b, undefined, { sensitivity: "base" })
);

Python

lines = ["banana", "Apple", "cherry", "ant"]

# Case-insensitive ascending
sorted_lines = sorted(lines, key=str.lower)
# ['ant', 'Apple', 'banana', 'cherry']

# Descending
sorted_desc = sorted(lines, key=str.lower, reverse=True)

# Numeric sort (natural sort with natsort library)
# pip install natsort
from natsort import natsorted
versions = ["v10.0", "v2.0", "v1.0"]
print(natsorted(versions))  # ['v1.0', 'v2.0', 'v10.0']

# Remove duplicates then sort
unique_sorted = sorted(set(lines), key=str.lower)

# Sort by line length
by_length = sorted(lines, key=len)

Go

package main

import (
    "sort"
    "strings"
    "fmt"
)

func main() {
    lines := []string{"banana", "Apple", "cherry", "ant"}

    // Case-insensitive ascending
    sort.Slice(lines, func(i, j int) bool {
        return strings.ToLower(lines[i]) < strings.ToLower(lines[j])
    })
    fmt.Println(lines) // [ant Apple banana cherry]

    // Descending (reverse after sort)
    sort.Slice(lines, func(i, j int) bool {
        return strings.ToLower(lines[i]) > strings.ToLower(lines[j])
    })

    // Remove duplicates
    seen := make(map[string]bool)
    unique := lines[:0]
    for _, v := range lines {
        key := strings.ToLower(v)
        if !seen[key] {
            seen[key] = true
            unique = append(unique, v)
        }
    }
}

PHP

<?php
$lines = ["banana", "Apple", "cherry", "ant"];

// Case-insensitive ascending
usort($lines, 'strcasecmp');
print_r($lines); // [ant, Apple, banana, cherry]

// Descending
usort($lines, fn($a, $b) => strcasecmp($b, $a));

// Natural/numeric sort
$versions = ["v10.0", "v2.0", "v1.0"];
natsort($versions);
print_r($versions); // [v1.0, v2.0, v10.0]

// Remove duplicates then sort
$unique = array_unique($lines);
usort($unique, 'strcasecmp');

// Sort by length
usort($lines, fn($a, $b) => strlen($a) - strlen($b));
?>

Locale-Aware Sorting

Different languages have different alphabetical rules:

  • In Swedish, ä sorts after z
  • In Spanish, ll was historically a single letter
  • In German, ü sorts near u or after z depending on context

JavaScript's localeCompare with a locale code handles this:

const names = ["Ångström", "Zebra", "Äpfel"];

// English sort (Ä → A)
names.sort((a, b) => a.localeCompare(b, "en"));
// ["Äpfel", "Ångström", "Zebra"]

// Swedish sort (Ä → after Z)
names.sort((a, b) => a.localeCompare(b, "sv"));
// ["Ångström", "Zebra", "Äpfel"]

For most English content, localeCompare(b, undefined, { sensitivity: "base" }) is the right default.


Quick Reference

Task JavaScript Python Go PHP
A→Z case-insensitive localeCompare + sensitivity:"base" sorted(key=str.lower) strings.ToLower compare usort + strcasecmp
Z→A localeCompare reversed reverse=True > instead of < strcasecmp($b,$a)
Numeric order localeCompare + numeric:true natsort regex extract int natsort()
By length a.length - b.length key=len len(a) < len(b) strlen($a)-strlen($b)
Remove duplicates new Set() set() map dedup array_unique()

Frequently Asked Questions

Does sorting modify the original array?
In JavaScript, Array.prototype.sort() mutates in place — use [...arr].sort() to get a new array. In Python, sorted() returns a new list while .sort() mutates. In Go, sort.Slice mutates the slice.

How do I sort a CSV column alphabetically?
Parse the CSV into rows, extract the column, sort the rows by that column's value, then re-serialize. Python's csv module with sorted(reader, key=lambda row: row[column_index].lower()) is the most concise approach.

What is "stable sort"?
A stable sort preserves the original relative order of equal elements. Python's sorted(), JavaScript's Array.sort() (since ES2019), and Java's Arrays.sort for objects are all stable. Go's sort.Slice is not stable — use sort.SliceStable if you need it.

How do I sort lines in a text file on the command line?
On Linux/macOS: sort file.txt (add -f for case-insensitive, -n for numeric, -r for reverse, -u for unique). On Windows PowerShell: Get-Content file.txt | Sort-Object.

What's the fastest way to sort a million lines?
Use sort on Linux — it's implemented in C, uses external merge sort for large files, and can handle files larger than RAM with -T /tmp. For in-memory work, Python's Timsort is highly optimized for real-world data.

Why does my sort put numbers before letters?
ASCII/Unicode assigns digits (48–57) lower values than letters (65–122), so 1line sorts before apple by default. Use a case-insensitive locale-aware sort or strip leading digits before comparing if that's not what you want.

Related tools

Keep reading

All Toolmingotools are free & run in your browser

No sign-up, no upload, no watermark. Your files never leave your device.

Browse all tools