我打这个并使用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
,平均超过百万次迭代)。标准字典的等效访问时间为1257ns。必须使两次检查有效地加倍,即2412ns。
在我的特殊情况下,我看到一个头部从服务器返回,它是驼峰式或小写的,这取决于我连接的网络(要调查的其他网络)。这样做的好处是,如果它得到解决,我可以删除扩展名,而不需要改变。此外,使用该代码的任何人都不需要记住任何解决方法 - 他们可以免费获得这个解决方案。
我检查,并没有看到ETag
被HTTPURLResponse
修改 - 如果我通过它ETag
,或Etag
我allHeaderFields
得到了那些回来。如果性能是一个问题,并且遇到此问题,则可以创建第二个下标,该下标需要包含数组的一个Hashable
结构。然后将其传递给Dictionary,并使用您想要处理的标签。
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"])])"
正如您所料,这几乎等同于制作单个字典查找。