1package smetrics
2
3import (
4	"math"
5)
6
7func Jaro(a, b string) float64 {
8	la := float64(len(a))
9	lb := float64(len(b))
10
11	// match range = max(len(a), len(b)) / 2 - 1
12	matchRange := int(math.Floor(math.Max(la, lb)/2.0)) - 1
13	matchRange = int(math.Max(0, float64(matchRange-1)))
14	var matches, halfs float64
15	transposed := make([]bool, len(b))
16
17	for i := 0; i < len(a); i++ {
18		start := int(math.Max(0, float64(i-matchRange)))
19		end := int(math.Min(lb-1, float64(i+matchRange)))
20
21		for j := start; j <= end; j++ {
22			if transposed[j] {
23				continue
24			}
25
26			if a[i] == b[j] {
27				if i != j {
28					halfs++
29				}
30				matches++
31				transposed[j] = true
32				break
33			}
34		}
35	}
36
37	if matches == 0 {
38		return 0
39	}
40
41	transposes := math.Floor(float64(halfs / 2))
42
43	return ((matches / la) + (matches / lb) + (matches-transposes)/matches) / 3.0
44}
45