扩展字典,其中Key的类型为String

时间:2015-10-16 21:44:50

标签: swift dictionary protocols swift2 extend

我想扩展一个Dictionary方法,但只有当Key的类型为String时才会这样。

我尝试这样做:

extension Dictionary where Key: String {
    mutating func lowercaseKeys() {
        for key in self.keys {
            self[key.lowercase] = self.removeValueForKey(key)
        }
    }
}

得到错误:

  

键入'Key'约束为非协议类型'String'

基于此错误消息,我可以告诉我只能使用协议进行此类过滤...有没有办法绕过这个?

2 个答案:

答案 0 :(得分:18)

我认为最符合您需求的协议是StringLiteralConvertible,只需几行,就可以让您完成此任务

extension Dictionary where Key: StringLiteralConvertible {
    mutating func setAllKeysLowercase() {
        for key in self.keys {
            if let lowercaseKey = String(key).lowercaseString as? Key {
                self[lowercaseKey] = self.removeValueForKey(key)
            }
        }
    }
}

var stringKeyDictionary = [ "Hello" : NSObject(), "World" : NSObject() ]
stringKeyDictionary.setAllKeysLowercase()
print( stringKeyDictionary )

// Prints: ["hello": <NSObject: 0x1007033c0>, "world": <NSObject: 0x1007033d0>]

var numberKeyDictionary = [ 0 : NSObject(), 1: NSObject() ]
numberKeyDictionary.setAllKeysLowercase() //< Won't compile, keys are not strings

答案 1 :(得分:1)

我已经为Swift 4更新了这个。

extension Dictionary where Key: StringProtocol {
    mutating func setAllKeysLowercase() {
        for key in self.keys {
            if let lowercaseKey = key.lowercased() as? Key {
                self[lowercaseKey] = self.removeValue(forKey: key)
            }
        }
    }
}

var stringKeyDictionary = [ "Hello" : 123, "World" : 456 ]
stringKeyDictionary.setAllKeysLowercase()
print( stringKeyDictionary )

打印:["hello": 123, "world": 456]

var numberKeyDictionary = [ 0 : 123, 1: 456 ]
numberKeyDictionary.setAllKeysLowercase()

给出错误:error: cannot use mutating member on immutable value: 'numberKeyDictionary' is immutable

由于StringLiteralConvertible已被弃用,我认为使用StringProtocol代替Swift4等效ExpressibleByStringLiteral可能更好。使用ExpressibleByStringLiteral表示Key不是String,因此不能使用lowercased之类的String方法。