Swift中的字符串比较不是传递性的

时间:2017-09-15 01:46:07

标签: swift

我遇到了这个例子,其中s1< s2和s2< s3但是(s1< s3)是假的:

var str1 = "あいかぎ"
var str2 = "あいかくしつ"
var str3 = "あいがみ:"

print(str1 < str2)       // True
print(str2 < str3)       // True
print(str1 < str3)       // False (?)

这是一个错误还是真的,我们不能依赖字符串比较是传递的(这会破坏我对字符串数组的排序)?我正在运行Swift 3。

更新:所有这些都是假的

print(str1 < str3)       // False (?)
print(str1 == str3)       // False (?)
print(str1 > str3)       // False (?)

所以有些字符串不能相互比较吗?

更新:How does the Swift string more than operator work中的评论指出&lt;运算符位于https://github.com/apple/swift/blob/master/stdlib/public/core/String.swift,比较由https://github.com/apple/swift/blob/master/stdlib/public/stubs/UnicodeNormalization.cpp中的_swift_stdlib_unicode_compare_utf8_utf8处理

更新:这些都是真的

print(str1 >= str3)  // True
print(str1 <= str3)  // True

更新:String.localizedCompare()也存在问题。有两个字符串,其中s1 = s2但s2> s2。 S1:

str1 = "bảo toàn"
str2 = "bảo tồn"

print(str1.localizedCompare(str2) == .orderedSame) // true
print(str2.localizedCompare(str1) == .orderedDescending) // true

1 个答案:

答案 0 :(得分:1)

看起来这不应该发生:

  

问:[Unicode校对算法]是否保持传递一致性?

     

答:是的,对于任何字符串A,B和C,如果A&lt; B和B&lt; C,然后A&lt; C.但是,实施者必须小心地生成能够精确再现Unicode校对算法结果的实现,因为它们优化了自己的算法。很容易执行不小心的优化 - 特别是使用增量比较算法 - 无法通过此测试。要检查的其他项目是重音基础之间的正确区分。例如,序列&lt; u-macron,u-diaeresis-macron&gt;应比较小于&lt; u-macron-diaeresis,u-macron&gt ;;这是次要的区分,基于重音的加权,必须与各自基本字母的主要权重正确关联。

(资料来源:Unicode Collation FAQ

UnicodeNormalization.cpp文件中,ucol_strcollucol_strcollIter被调用,它们是the ICU project的一部分。这可能是Swift标准库或ICU项目中的错误。 I reported this issue to the Swift Bug Tracker