Skip to content

Instantly share code, notes, and snippets.

@Codelaby
Created November 22, 2023 15:38
Show Gist options
  • Save Codelaby/3358f8bd6a88ae87962dd72bab076d7f to your computer and use it in GitHub Desktop.
Save Codelaby/3358f8bd6a88ae87962dd72bab076d7f to your computer and use it in GitHub Desktop.
Metaphone Spanish
import Foundation
class MetaphoneSpanish {
private class func stringAt(_ string: String, _ start: Int, _ length: Int, _ list: [String]) -> Bool {
if start < 0 || start >= string.count {
return false
}
let substring = string[string.index(string.startIndex, offsetBy: start)..<string.index(string.startIndex, offsetBy: start+length)]
for expr in list {
if substring.contains(expr) {
return true
}
}
return false
}
private class func isVowel(_ string: String, _ position: Int) -> Bool {
let character = string[string.index(string.startIndex, offsetBy: position)]
return ["A", "E", "I", "O", "U"].contains(String(character))
}
private class func translateCharacters(_ string: String) -> String {
let translated: [String: String] = [
"á": "A",
"ch": "X",
"ç": "S",
"é": "E",
"í": "I",
"ó": "O",
"ú": "U",
"ñ": "NY",
"gü": "W",
"ü": "U",
"b": "V",
// "z": "S",
"ll": "Y"
]
var result = string
for (key, value) in translated {
result = result.replacingOccurrences(of: key, with: value)
}
return result
}
func metaphone(_ string: String, _ phonemes: Int = 0) -> String {
var metaKey = ""
var currentPos = 0
var originalString = string + " "
originalString = MetaphoneSpanish.translateCharacters(originalString)
originalString = originalString.uppercased()
while phonemes == 0 || metaKey.count < phonemes {
if currentPos >= originalString.count {
break
}
let currentChar = originalString[originalString.index(originalString.startIndex, offsetBy: currentPos)]
if MetaphoneSpanish.isVowel(originalString, currentPos) && currentPos == 0 {
metaKey += String(currentChar)
currentPos += 1
} else {
let singleSoundChars = ["D", "F", "J", "K", "M", "N", "P", "T", "V", "L", "Y"]
if MetaphoneSpanish.stringAt(originalString, currentPos, 1, singleSoundChars) {
metaKey += String(currentChar)
if originalString[originalString.index(originalString.startIndex, offsetBy: currentPos + 1)] == currentChar {
currentPos += 2
} else {
currentPos += 1
}
} else {
if currentChar == "C" {
if originalString[originalString.index(originalString.startIndex, offsetBy: currentPos + 1)] == "C" {
metaKey += "X"
currentPos += 2
} else if MetaphoneSpanish.stringAt(originalString, currentPos, 2, ["CE", "CI"]) {
metaKey += "Z"
currentPos += 2
} else {
metaKey += "K"
currentPos += 1
}
} else if currentChar == "G" {
if MetaphoneSpanish.stringAt(originalString, currentPos, 2, ["GE", "GI"]) {
metaKey += "J"
currentPos += 2
} else {
metaKey += "G"
currentPos += 1
}
} else if currentChar == "H" {
if MetaphoneSpanish.isVowel(originalString, currentPos + 1) {
metaKey += String(originalString[originalString.index(originalString.startIndex, offsetBy: currentPos + 1)])
currentPos += 2
} else {
metaKey += "H"
currentPos += 1
}
} else if currentChar == "Q" {
if originalString[originalString.index(originalString.startIndex, offsetBy: currentPos + 1)] == "U" {
currentPos += 2
} else {
currentPos += 1
}
metaKey += "K"
} else if currentChar == "W" {
metaKey += "U"
currentPos += 1
} else if currentChar == "R" {
currentPos += 1
metaKey += "R"
} else if currentChar == "S" {
if !MetaphoneSpanish.isVowel(originalString, currentPos + 1) && currentPos == 0 {
metaKey += "ES"
currentPos += 1
} else {
currentPos += 1
metaKey += "S"
}
} else if currentChar == "Z" {
currentPos += 1
metaKey += "Z"
} else if currentChar == "X" {
if !MetaphoneSpanish.isVowel(originalString, currentPos + 1)
&& originalString.count > 1
&& currentPos == 0 {
metaKey += "EX"
currentPos += 1
} else {
metaKey += "X"
currentPos += 1
}
} else {
currentPos += 1
}
}
}
}
metaKey = metaKey.trimmingCharacters(in: .whitespacesAndNewlines)
return metaKey
}
}
// Example usage:
let metaphoneSpanish = MetaphoneSpanish()
let metaphoneKey = metaphoneSpanish.metaphone("El Parlamento Europeo acaba de dar un espaldarazo"" ")
print(metaphoneKey)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment