- read

Get next rune with Go

Daniel Carvallo 3

How to increment a rune by one and get the next one?

Alphabet
Photo by Sven Brandsma on Unsplash

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.

getNextRune(ch rune)