我点击了这个并使用扩展来解决它Dictionary
来创建自定义下标。
extension Dictionary {
subscript(key: String) -> Value? {
get {
let anyKey = key as! Key
if let value = self[anyKey] {
return value // 1213ns
}
if let value = self[key.lowercased() as! Key] {
return value // 2511ns
}
if let value = self[key.capitalized as! Key] {
return value // 8928ns
}
for (storedKey, storedValue) in self {
if let stringKey = storedKey as? String {
if stringKey.caseInsensitiveCompare(key) == .orderedSame {
return storedValue // 22317ns
}
}
}
return nil
}
set {
self[key] = newValue
}
}
}
评论中的时间来自对不同场景的基准测试(优化构建-Os
,平均超过 1,000,000 次迭代)。标准字典的等效访问时间为 1257ns。必须进行两次检查有效地将其翻倍,即 2412ns。
在我的特定情况下,我看到从服务器返回的标头是驼峰式或小写的,具体取决于我连接的网络(还有其他要调查的内容)。这样做的好处是,如果它得到修复,我可以删除扩展而无需更改任何其他内容。此外,使用该代码的任何其他人都不需要记住任何解决方法——他们免费获得这个。
我检查并没有看到ETag
被修改HTTPURLResponse
- 如果我通过了它ETag
,或者Etag
我把它们拿回来了allHeaderFields
。如果性能是一个问题,并且您遇到此问题,您可以创建第二个下标,该下标采用Hashable
包含数组的结构。然后将其传递给字典,并带有您要处理的标签。
struct DictionaryKey: Hashable {
let keys: [String]
var hashValue: Int { return 0 } // Don't care what is returned, not going to use it
}
func ==(lhs: DictionaryKey, rhs: DictionaryKey) -> Bool {
return lhs.keys == rhs.keys // Just filling expectations
}
extension Dictionary {
subscript(key: DictionaryKey) -> Value? {
get {
for string in key.keys {
if let value = self[string as! Key] {
return value
}
}
return nil
}
}
}
print("\(allHeaderFields[DictionaryKey(keys: ["ETag", "Etag"])])"
正如您所料,这几乎等同于进行单独的字典查找。