I want to have extend a method of Dictionary but only if Key is of type String.
I try doing this:
extension Dictionary where Key: String {
mutating func lowercaseKeys() {
for key in self.keys {
self[key.lowercase] = self.removeValueForKey(key)
}
}
}
And get error:
Type 'Key' constrained to non-protocol type 'String'
Based on this error message I can tell that I can only do this kind of filtering with protocols... Is there a way to by-pass this?
I believe the closest protocol that meets your needs is StringLiteralConvertible
, which, with a few extra lines, will let you accomplish this
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
I've updated this for 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 )
Prints: ["hello": 123, "world": 456]
var numberKeyDictionary = [ 0 : 123, 1: 456 ]
numberKeyDictionary.setAllKeysLowercase()
gives error: error: cannot use mutating member on immutable value: 'numberKeyDictionary' is immutable
Since StringLiteralConvertible
is deprecated I thought it might be better to use StringProtocol
instead of the Swift4 equivalent ExpressibleByStringLiteral
. Using ExpressibleByStringLiteral
means the Key isn't a String so can't use String methods like lowercased
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With