【发布时间】:2015-10-04 22:54:39
【问题描述】:
我正在制作一个类似于String 的结构,只是它只处理 Unicode UTF-32 标量值。因此,它是一个UInt32 的数组。 (有关更多背景信息,请参阅this question。)
我想做什么
我希望能够使用我的自定义 ScalarString 结构作为字典中的键。例如:
var suffixDictionary = [ScalarString: ScalarString]() // Unicode key, rendered glyph value
// populate dictionary
suffixDictionary[keyScalarString] = valueScalarString
// ...
// check if dictionary contains Unicode scalar string key
if let renderedSuffix = suffixDictionary[unicodeScalarString] {
// do something with value
}
问题
为此,ScalarString 需要实现 Hashable Protocol。我以为我可以做这样的事情:
struct ScalarString: Hashable {
private var scalarArray: [UInt32] = []
var hashValue : Int {
get {
return self.scalarArray.hashValue // error
}
}
}
func ==(left: ScalarString, right: ScalarString) -> Bool {
return left.hashValue == right.hashValue
}
但后来我发现Swift arrays 没有hashValue。
我读到的
Strategies for Implementing the Hashable Protocol in Swift 这篇文章有很多很棒的想法,但我没有看到它们在这种情况下会很好用。具体来说,
-
对象属性(数组没有
hashValue) - ID 属性(不确定如何很好地实现)
- 公式(似乎任何用于 32 位整数字符串的公式都会占用大量处理器并且有大量整数溢出)
- ObjectIdentifier(我使用的是结构,而不是类)
- 从 NSObject 继承(我使用的是结构,而不是类)
以下是我阅读的其他一些内容:
- Implementing Swift's Hashable Protocol
- Swift Comparison Protocols
- Perfect hash function
- Membership of custom objects in Swift Arrays and Dictionaries
- How to implement Hashable for your custom class
- Writing a good Hashable implementation in Swift
问题
Swift 字符串有一个hashValue 属性,所以我知道这是可能的。
如何为我的自定义结构创建hashValue?
更新
更新 1: 我想做一些不涉及转换为 String 然后使用 String 的 hashValue 的事情。我制作自己的结构的全部目的是为了避免进行大量的String 转换。 String 从某处得到hashValue。看来我可以用同样的方法得到它。
更新 2: 我一直在研究其他上下文中字符串哈希码算法的实现。不过,我很难知道哪个是最好的并用 Swift 表达它们。
- Java
hashCodealgorithm - C algorithms
- hash function for string(C 中的 SO 问题和答案)
- Hashing tutorial(弗吉尼亚理工大学算法可视化研究组)
- General Purpose Hash Function Algorithms
更新 3
我不希望导入任何外部框架,除非这是推荐的方式。
我使用 DJB 哈希函数提交了一个可能的解决方案。
【问题讨论】:
-
旁白:UTF-32 不能处理一个代码单元中的所有 unicode 字符。有代理对、表情符号颜色和奇怪的东西,比如需要不止一个的标志。
-
Unicode 使用 21 位来存储它的所有代码点,因此 UTF-32 足以处理上面planes 中的标志、表情符号和其他东西。但是,UTF-16 编码需要代理对来引用平面 0 之上的任何 Unicode 字符。也就是说,
UInt32无法 处理 SwiftCharacters(扩展字形簇),它可以由多个 Unicode 标量值。我自己制作ScalarString的原因是为了避免Character的一些歧义。 -
从 Swift 4.2 开始,不再需要定义自己的哈希组合器,请参阅我对 codereview.stackexchange.com/a/111573/35991 的更新。
-
@MartinR,感谢您在此处留下链接。我还在下面的回答中引用了你。
标签: ios arrays string swift hashtable