如何将Objective-C遍历字符串字符的逻辑正确转换为Swift实现
问题根因
两个版本计算结果不一致的核心原因是字符取值逻辑完全不匹配:
- Objective-C 中
[string characterAtIndex:i]返回的是unichar类型值,本质是字符串对应位置的UTF-16编码单元原始数值,OC逻辑累加的就是这个原始编码值 - 你写的Swift版本误用了
Character.wholeNumberValue属性:这个属性仅会把代表阿拉伯数字的字符(例如字符"9")转换为对应的整数值9,所有非数字字符(包括输入里的J、o、空格、i等)调用该属性都会返回nil,最终走?? 0分支累加0,计算结果自然完全错误,输入"Johny ivan"时最终取模得到0。
对齐OC逻辑的正确Swift实现
要和OC版本计算结果完全一致,必须对齐OC的遍历规则:按NSString的UTF-16编码单元遍历,累加每个单元的原始数值,代码如下:
func hex(for string: String) -> String { var charIndex = 0 // 与NSString的characterAtIndex:行为完全对齐,遍历UTF-16编码单元 for utf16Unit in string.utf16 { charIndex += Int(utf16Unit) } let colors = [ "1abc9c", "2ecc71", "3498db", "9b59b6", "34495e", "16a085", "27ae60", "2980b9", "8e44ad", "2c3e50", "f1c40f", "e67e22", "e74c3c", "95a5a6", "f39c12", "d35400", "c0392b", "bdc3c7", "7f8c8d" ] charIndex %= colors.count print(">>po modulo \(charIndex)") // 输入"Johny ivan"时输出13,与OC结果一致 return colors[charIndex] }
注意事项
- 不要直接遍历
String的Character集合:Character对应扩展字形集群,和OC按UTF-16位置取字符的逻辑不对等,遇到emoji、组合重音字符等特殊内容时,计算结果会和OC版本出现偏差 - 访问字符串的
utf16视图是和Objective-CNSString字符访问行为100%匹配的方式,可保证任意输入下计算结果和原OC实现完全一致。
内容的提问来源于stack exchange,提问作者kunass2
相关产品推荐
相关产品推荐

