私はこれをヒットし、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で出てきました。 2つの小切手を作ることが効果的に2倍になりました。
私の具体的なケースでは、私が接続していたネットワーク(調査する何か他のもの)によって、ラクダのケースか小文字だったサーバーからヘッダが戻ってくるのを見ていました。これは、修正が必要な場合は、拡張機能を削除するだけで、変更する必要はないという利点があります。また、コードを使用している誰もが何らかの回避策を思い出す必要はありません。無料でこのコードを取得します。
私がチェックしETag
がHTTPURLResponse
によって変更されて表示されませんでした - 私はそれをETag
、またはEtag
を通過した場合、私はallHeaderFields
にそれらの背中を得ました。パフォーマンスが懸念され、この問題が発生した場合、配列を含むHashable
構造体を受け取る2番目の添字を作成できます。次に、それを処理したいタグとともに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"])])"
これは、予想通り、個々の辞書のルックアップとほぼ同じです。