gstr_soundex.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. // Copyright 2018 gf Author(https://github.com/gogf/gf). All Rights Reserved.
  2. //
  3. // This Source Code Form is subject to the terms of the MIT License.
  4. // If a copy of the MIT was not distributed with this file,
  5. // You can obtain one at https://github.com/gogf/gf.
  6. package gstr
  7. // Soundex calculates the soundex key of a string.
  8. // See http://php.net/manual/en/function.soundex.php.
  9. func Soundex(str string) string {
  10. if str == "" {
  11. panic("str: cannot be an empty string")
  12. }
  13. table := [26]rune{
  14. '0', '1', '2', '3', // A, B, C, D
  15. '0', '1', '2', // E, F, G
  16. '0', // H
  17. '0', '2', '2', '4', '5', '5', // I, J, K, L, M, N
  18. '0', '1', '2', '6', '2', '3', // O, P, Q, R, S, T
  19. '0', '1', // U, V
  20. '0', '2', // W, X
  21. '0', '2', // Y, Z
  22. }
  23. last, code, small := -1, 0, 0
  24. sd := make([]rune, 4)
  25. // build soundex string
  26. for i := 0; i < len(str) && small < 4; i++ {
  27. // ToUpper
  28. char := str[i]
  29. if char < '\u007F' && 'a' <= char && char <= 'z' {
  30. code = int(char - 'a' + 'A')
  31. } else {
  32. code = int(char)
  33. }
  34. if code >= 'A' && code <= 'Z' {
  35. if small == 0 {
  36. sd[small] = rune(code)
  37. small++
  38. last = int(table[code-'A'])
  39. } else {
  40. code = int(table[code-'A'])
  41. if code != last {
  42. if code != 0 {
  43. sd[small] = rune(code)
  44. small++
  45. }
  46. last = code
  47. }
  48. }
  49. }
  50. }
  51. // pad with "0"
  52. for ; small < 4; small++ {
  53. sd[small] = '0'
  54. }
  55. return string(sd)
  56. }