// Package natsort compares strings the way humans number things: "page2" sorts // before "page10". Lexical ordering gets this wrong, which silently shuffles // comic pages and audiobook tracks. package natsort import "strings" // Less reports whether a sorts before b. func Less(a, b string) bool { ai, bi := 0, 0 for ai < len(a) && bi < len(b) { ad, bd := isDigit(a[ai]), isDigit(b[bi]) if ad && bd { // Compare the whole digit runs as numbers, ignoring leading zeros // so "01" and "1" are equal. as, bs := ai, bi for ai < len(a) && isDigit(a[ai]) { ai++ } for bi < len(b) && isDigit(b[bi]) { bi++ } an := strings.TrimLeft(a[as:ai], "0") bn := strings.TrimLeft(b[bs:bi], "0") if len(an) != len(bn) { return len(an) < len(bn) } if an != bn { return an < bn } continue } if a[ai] != b[bi] { return a[ai] < b[bi] } ai++ bi++ } return len(a)-ai < len(b)-bi } func isDigit(c byte) bool { return c >= '0' && c <= '9' }