Case Insensitive Dictionary in Swift

Given Dictionarywhose Keytype it is String, is there a way to access a case-insensitive value? For example:

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

Is there a way to call dict["NAME"], dict["nAmE"]etc, as well as stil get "John"?

+4
source share
2 answers

Swift supports multiple subscribers, so you can use this to define access-insensitve accessor:

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

, 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"
+1

Source: https://habr.com/ru/post/1612015/


All Articles