Get next rune with Go
How to increment a rune by one and get the next one?
Let’s say we have ‘a’ and we want ‘b’, easy, just increment the ASCII decimal value:
97 + 1 = 98 a -> b
But what would happen if we increment by ‘z’ by one? We should generate the next character which would be the the curly bracket ‘{‘, but this is not the case, since we are only looking for characters from the alphabet.
122 + 1 = 123 z -> {
We need a stop condition when we detect the last character of the alphabet and return the first character of the alphabet. A simple if-else
would suffice as a stop condition.
if ch == 'z' {
return 'a'
} else {
return string(ch + 1)
}
It could also be a switch with only one case.
switch {
case ch == 'z':
return 'a'
default:
return string(ch + 1)
}
But could we reduce the above to a single line, right? Could we have a stop condition that depends on the length of the alphabet and not on the if-else
or switch
statements?
And the answer is yes.
A more elaborate stopping condition can be created taking into consideration two things, that English alphabet consists of 26 characters and that we can use this constant to iterate over its ASCII decimal representation via modulo.
For a 3 character alphabet we can use the following representation, where the modulo 3 of any k
is always within the numbers 0, 1, 2.
0 % 3 = 0
1 % 3 = 1
2 % 3 = 2
3 % 3 = 0
4 % 3 = 1
...
So we can do the calculation (k % m) + 1 = k + 1
to get the next character based on the modulo being calculated, in this example k = 1
and m = 3
(1 % 3) + 1 = 2
(2 % 3) + 1 = 3
(3 % 3) + 1 = 1
(4 % 3) + 1 = 2
(5 % 3) + 1 = 3
(6 % 3) + 1 = 1
...
More generally, we need the first character of our alphabet (in decimal ASCII) and the last character to be able to rotate the characters within these limits. Here the alphabet is used with non-capital a-z
letters, however capital letters can be used equally.
(k - 'a') % ('z' - 'a' + 1) + 'a' = k + 1
For k = 122
which is z
, a first character of the alphabet with decimal ASCII representation of 97
and last character with representation of 122
we have the final representation:
(122 + 1 - 97) % (122 - 97 + 1) + 97 = 97
( 97 + 1 - 97) % (122 - 97 + 1) + 97 = 98
( 98 + 1 - 97) % (122 - 97 + 1) + 97 = 99
Written in Go without using if-else
or switch
it would look like this.
