尝试修改表情符号序列时出现问题

时间:2016-09-18 02:04:54

标签: swift emoji

我有以下函数,它带有一个带有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中的第二个键。 男性符号和变体选择器也会出现类似问题。

任何想法为什么会发生这种情况?

1 个答案:

答案 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("⛹⛹⛹")