Iterate runes

Hamming
Hamming in Go
// Package hamming is a small library for determining the hamming distance between two strands.
package hamming

import (
	"errors"
	"unicode/utf8"
)

// Distance accepts two strands and returns their hamming distance.
func Distance(strand1 string, strand2 string) (distance int, err error) {
	if utf8.RuneCountInString(strand1) != utf8.RuneCountInString(strand2) {
		return 0, errors.New("strands must be of equal length")
	}

	strand1Runes := []rune(strand1)
	strand2Runes := []rune(strand2)
	
	for idx, rooney := range strand1Runes {
		if rooney != strand2Runes[idx] {
			distance++
		}
	}
	return distance, nil
}

The Distance() function is defined with named return values which are initialized with their zero values.

The utf8 RuneCountInString() function is used to compare the lengths of the strands in runes. This isn't necessary when all of the input characters are single-byte ASCII, but if any character was a multi-byte character, then the RuneCountInString() function would be needed to give the accurate number of characters. The len() function used on a string would give the number of bytes, which would be inaccurate for returning the number of characters for multi-byte characters.

If the strands don't have the same number of runes, then 0 is returned along with the new error.

The two strands are used to create rune slices.

The ways to iterate characters are by Unicode runes, or by each letter being a string, or by each letter being a byte. The runes are from range on a string, the strings from Split(), and the bytes from indexing into the string. Another way to iterate runes is to convert the string to a rune slice and range on it. The difference between ranging on a rune slice vs ranging on a string is that the index returned from a string is the position of the next rune in bytes, not which rune it is. For example, if the first unicode character is two bytes, then the second unicode character index will be 2 when ranging on a string and 1 when ranging on a rune slice.

The runes of the first strand are iterated. The rune in each iteration is compared with the rune at the same index in the other strand. If the runes are different at the same index for each strand, then the distance is incremented. After the loop is finished, distance is returned along with a nil error.

20th Nov 2024 · Found it useful?