給定Dictionary
的Key
類型String
,有沒有辦法以不區分大小寫的方式訪問該值?例如:不區分大小寫Swift的字典
let dict = [
"name": "John",
"location": "Chicago"
]
有沒有一種方法來調用dict["NAME"], dict["nAmE"]
等,史迪威得到"John"
?
給定Dictionary
的Key
類型String
,有沒有辦法以不區分大小寫的方式訪問該值?例如:不區分大小寫Swift的字典
let dict = [
"name": "John",
"location": "Chicago"
]
有沒有一種方法來調用dict["NAME"], dict["nAmE"]
等,史迪威得到"John"
?
夫特支持多個下標,以便可以利用這一點來定義的情況下,鈍感存取:
extension Dictionary where Key : StringLiteralConvertible {
subscript(ci key : Key) -> Value? {
get {
let searchKey = String(key).lowercaseString
for k in self.keys {
let lowerK = String(k).lowercaseString
if searchKey == lowerK {
return self[k]
}
}
return nil
}
}
}
// Usage:
let dict = [
"name": "John",
"location": "Chicago",
]
print(dict[ci: "NAME"]) // John
print(dict[ci: "lOcAtIoN"]) // Chicago
此擴展被限制在Dictionary
其Key
是String
型的(如小寫是無意義的與其它數據類型)。然而,Swift會抱怨約束一個泛型類型爲struct
。最接近String
的協議是StringLiteralConvertible
。
請注意,如果你有2個鍵,其小寫形式是相同的,也不能保證你會得到其中的一個:
let dict = [
"name": "John",
"NAME": "David",
]
print(dict[ci: "name"]) // no guarantee that you will get David or John.
一個更簡潔的方法,快速的4:
extension Dictionary where Key == String {
subscript(caseInsensitive key: Key) -> Value? {
get {
if let k = keys.first(where: { $0.caseInsensitiveCompare(key) == .orderedSame }) {
return self[k]
}
return nil
}
set {
if let k = keys.first(where: { $0.caseInsensitiveCompare(key) == .orderedSame }) {
self[k] = newValue
} else {
self[key] = newValue
}
}
}
}
// Usage:
var dict = ["name": "John"]
dict[caseInsensitive: "NAME"] = "David" // overwrites "name" value
print(dict[caseInsensitive: "name"]!) // outputs "David"
像在現實世界鍵應該是相同的。你無法處理錯別字,你應該修復它們。 – vikingosegundo
+1 to @vikingosegundo評論。你爲什麼需要這個?例如,爲什麼不把所有密鑰都存儲爲小寫(例如,如果情況稍後會涉及)。看起來像一個體面的解決方案,應該不是這樣的問題:D –
我不得不在最近的項目中使用它。字典從JSON轉換而來,我接受一個輸入,返回值,而不管鍵的大小寫。我無法將所有鍵都轉換爲小寫字母,因爲我不得不將其發回其他web服務。有關更多上下文,請搜索「不區分大小寫的字典」,您幾乎可以在每個有字典的語言中找到問題。 –