我有以下函数,它带有一个带有emojis的字符串,如果它的序列表情符号为a + b,它将保持原样,它会将b更改为不同的表情符号
func changeEmoji(givenString:String)->(String){
let emojiDictionary :[String:String] = [
"⛹" : "⛹",
"♀️" : "",
"" : "",
"♂️" :"",
]
let stringCharacters=Array(givenString.characters)
var returnedString=String()
for character in stringCharacters{
if emojiDictionary[String(character)] == nil {
return "error"
}
else {
returnedString=returnedString+emojiDictionary[String(character)]!
}
}
return returnedString
}
我没有问题
changeEmoji(givenString: "⛹⛹")
输出:"⛹⛹"
但:
changeEmoji(givenString: "⛹⛹⛹♀️")
输出"错误"虽然它不应该是♀女性符号和变异选择器-16是我的emojiDictionary中的第二个键。 男性符号和变体选择器也会出现类似问题。
任何想法为什么会发生这种情况?
答案 0 :(得分:1)
问题是“⛹♀️”由3个Swift Character
(又名扩展的字形簇)组成:
“⛹”(U + 26F9带球的人)
“”(U + 1F3FB Emoji Modifier Fitzpatrick Type-1-2,U + 200D ZERO WIDTH JOINER)
“♀️”(U + 2640女性签名,U + FE0F VARIATION SELECTOR-16)
但是,您的emojiDictionary
只包含一个“”(U + 1F3FB Emoji Modifier Fitzpatrick Type-1-2),它与“⛹♀️”的第二个Character
不匹配它缺少零宽度连接器。
因此,最简单的解决方案是在字典中添加另一个键,以包含表情符号修饰符Fitzpatrick Type-1-2字符,后缀为零宽度。最明确的方法是使用unicode转义序列\u{200D}
对其进行后缀。
例如:
func changeEmoji(givenString: String) -> String? {
// I have included the unicode point breakdowns for clarity
let emojiDictionary : [String : String] = [
"⛹" : "⛹", // 26F9 : 26F9
"♀️" : "", // 2640, fe0f : 1f469
"" : "", // 1f3fb : 1f4a4
"\u{200D}" : "", // 1f3fb, 200d : 1f4a4
"♂️" :"" // 2642, fe0f : 1f468
]
// Convert characters of string to an array of string characters,
// given that you're just going to use the String(_:) initialiser later.
let stringCharacters = givenString.characters.map(String.init(_:))
var returnedString = ""
for character in stringCharacters {
guard let replacementCharacter = emojiDictionary[character] else {
// I would advise making your method return an optional
// in cases where the string can't be converted.
// Failure is shown by the return of nil, rather than some
// string sentinel.
return nil
}
returnedString += replacementCharacter
}
return returnedString
}
print(changeEmoji(givenString: "⛹⛹⛹♀️")) // Optional("⛹⛹⛹")