我打這個並使用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"])])"
正如您所料,這幾乎等同於製作單個字典查找。