Description
Currently, if you need to compare two strings or sort a list of strings lexicographically by codepoint, then you need to write your own comparison routine. This is an unsatisfactory state of affairs since you can't add your own comparison operators (or anything else) to the built-in String
class or inherit from it.
I therefore propose that we add a compareTo
method and comparison operators to the String
class so that it will be as easy to compare two strings or sort a list of strings as it is to perform the same operations on numbers.
As we need to work at the codepoint rather than the byte level, it will probably be quick enough to do this from the Wren side and here's my attempt at some code which is essentially what I've been using myself for the last 3 years or so, albeit in the guise of static methods of a proxy class:
class String is Sequence {
/* existing stuff */
// Compares this to another string lexicographically by codepoint.
// Returns -1, 0 or +1 depending on whether
// this < other, this == other or this > other respectively.
compareTo(other) {
if (!(other is String)) Fiber.abort("Other must be a string")
if (this == other) return 0
var cp1 = this.codePoints
var cp2 = other.codePoints
var len = (cp1.count <= cp2.count) ? cp1.count : cp2.count
for (i in 0...len) {
if (cp1[i] < cp2[i]) return -1
if (cp1[i] > cp2[i]) return 1
}
return (cp1.count < cp2.count) ? -1 : 1
}
// Comparison operators.
< (other) { compareTo(other) < 0 }
<= (other) { compareTo(other) <= 0 }
> (other) { compareTo(other) > 0 }
>= (other) { compareTo(other) >= 0 }
}
I look forward to receiving comments on this proposal and any suggestions for improving the code.