【问题标题】:String comparison in Swift is not transitiveSwift 中的字符串比较不是传递的
【发布时间】:2017-09-15 01:46:07
【问题描述】:

我遇到了这个例子,其中 s1

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中的评论指出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 > s1:

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

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

【问题讨论】:

  • 另外,print(str1 &gt;= str3)print(str1 &lt;= str3) 都打印为 true :)
  • 感觉答案就在这里:stackoverflow.com/a/25775112/341994
  • 但这不是他要求的。他想知道某事,而不是某事。他不是在寻找解决方法,而是在寻找解释。我也是。
  • 一个稍微短一点的例子是var str1 = "かぎ"; var str2 = "かく"; var str3 = "がみ"。规范化形式 D 中的 Unicode 标量分别为 U+304B U+304D U+3099U+304B U+304FU+304B U+3099 U+307F。所以str1 &lt; str3 应该是真的,我不知道为什么不是。
  • @LeoDabus String.localizedCompare() 也存在相关问题。我用一个例子更新了这个问题。

标签: swift


【解决方案1】:

看起来这不应该发生:

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

A:是的,对于任何字符串 A、B 和 C,如果 A 应该比较小于 ;这是次要区别,基于重音的权重,必须正确地与它们各自的基本字母的主要权重相关联。

(来源:Unicode Collation FAQ

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

【讨论】:

    猜你喜欢
    • 2015-07-23
    • 1970-01-01
    • 2014-08-06
    • 2013-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多