(a: string, z: string)
| 6 | * instead of strings. |
| 7 | */ |
| 8 | export function compare(a: string, z: string) { |
| 9 | let aLen = a.length |
| 10 | let zLen = z.length |
| 11 | let minLen = aLen < zLen ? aLen : zLen |
| 12 | |
| 13 | for (let i = 0; i < minLen; i++) { |
| 14 | let aCode = a.charCodeAt(i) |
| 15 | let zCode = z.charCodeAt(i) |
| 16 | |
| 17 | // If both are numbers, compare them as numbers instead of strings. |
| 18 | if (aCode >= ZERO && aCode <= NINE && zCode >= ZERO && zCode <= NINE) { |
| 19 | let aStart = i |
| 20 | let aEnd = i + 1 |
| 21 | let zStart = i |
| 22 | let zEnd = i + 1 |
| 23 | |
| 24 | // Consume the number |
| 25 | aCode = a.charCodeAt(aEnd) |
| 26 | while (aCode >= ZERO && aCode <= NINE) aCode = a.charCodeAt(++aEnd) |
| 27 | |
| 28 | // Consume the number |
| 29 | zCode = z.charCodeAt(zEnd) |
| 30 | while (zCode >= ZERO && zCode <= NINE) zCode = z.charCodeAt(++zEnd) |
| 31 | |
| 32 | let aNumber = a.slice(aStart, aEnd) |
| 33 | let zNumber = z.slice(zStart, zEnd) |
| 34 | |
| 35 | let diff = Number(aNumber) - Number(zNumber) |
| 36 | if (diff) return diff |
| 37 | |
| 38 | // Fallback case if numbers are the same but the string representation |
| 39 | // is not. Fallback to string sorting. E.g.: `0123` vs `123` |
| 40 | if (aNumber < zNumber) return -1 |
| 41 | if (aNumber > zNumber) return 1 |
| 42 | |
| 43 | // Continue with the next character otherwise short strings will appear |
| 44 | // after long ones when containing numbers. E.g.: |
| 45 | // - bg-red-500/70 |
| 46 | // - bg-red-500 |
| 47 | continue |
| 48 | } |
| 49 | |
| 50 | // Continue if the characters are the same |
| 51 | if (aCode === zCode) continue |
| 52 | |
| 53 | // Otherwise, compare them as strings |
| 54 | return aCode - zCode |
| 55 | } |
| 56 | |
| 57 | // If we got this far, the strings are equal up to the length of the shortest |
| 58 | // string. The shortest string should come first. |
| 59 | |
| 60 | return a.length - z.length |
| 61 | } |
no outgoing calls
no test coverage detected