2015-10-17 90 views
4

給定DictionaryKey類型String,有沒有辦法以不區分大小寫的方式訪問該值?例如:不區分大小寫Swift的字典

let dict = [ 
    "name": "John", 
    "location": "Chicago" 
] 

有沒有一種方法來調用dict["NAME"], dict["nAmE"]等,史迪威得到"John"

回答

4

夫特支持多個下標,以便可以利用這一點來定義的情況下,鈍感存取:

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 

此擴展被限制在DictionaryKeyString型的(如小寫是無意義的與其它數據類型)。然而,Swift會抱怨約束一個泛型類型爲struct。最接近String的協議是StringLiteralConvertible

請注意,如果你有2個鍵,其小寫形式是相同的,也不能保證你會得到其中的一個:

let dict = [ 
    "name": "John", 
    "NAME": "David", 
] 

print(dict[ci: "name"]) // no guarantee that you will get David or John. 
+0

像在現實世界鍵應該是相同的。你無法處理錯別字,你應該修復它們。 – vikingosegundo

+0

+1 to @vikingosegundo評論。你爲什麼需要這個?例如,爲什麼不把所有密鑰都存儲爲小寫(例如,如果情況稍後會涉及)。看起來像一個體面的解決方案,應該不是這樣的問題:D –

+0

我不得不在最近的項目中使用它。字典從JSON轉換而來,我接受一個輸入,返回值,而不管鍵的大小寫。我無法將所有鍵都轉換爲小寫字母,因爲我不得不將其發回其他web服務。有關更多上下文,請搜索「不區分大小寫的字典」,您幾乎可以在每個有字典的語言中找到問題。 –

1

一個更簡潔的方法,快速的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"