Example #1
0
// SuggestCommands can be used to match a given word
// which is very similar to one among the list of available commands.
func SuggestCommands(given string, available []string) []string {
	commandSet := make(map[string]struct{})
	for _, command := range available {
		commandSet[command] = struct{}{}
	}
	if len(commandSet) == 0 || given == "" {
		return nil
	}

	if _, ok := commandSet[given]; ok {
		return nil
	}

	var scores cmdScores

	for command := range commandSet {
		levenshtein := smetrics.WagnerFischer(command, given, 1, 1, 1)
		jaroWinkler := smetrics.JaroWinkler(command, given, 0.7, 4)

		if levenshtein > levenThreshold {
			continue
		}
		if jaroWinkler < jaroThreshold {
			continue
		}
		scores = append(
			scores,
			cmdScore{
				name:        command,
				levenshtein: levenshtein,
				jaroWinkler: jaroWinkler,
			},
		)
	}
	if len(scores) == 0 {
		return nil
	}
	sort.Sort(scores)

	levenshtein := scores[0].levenshtein

	var matches []string
	for _, score := range scores {
		if score.levenshtein != levenshtein {
			break
		}
		matches = append(matches, score.name)
	}

	return matches
}
Example #2
0
//TODO this needs to be improved a lot!
func distance(a, b string) float32 {
	return float32(smetrics.WagnerFischer(a, b, 1, 1, 2)) / float32(len(a)+len(b))
}