How can I check if a key exists in a dictionary? My dictionary is of type [Type:Type?]
.
I can\'t simply check dictionary[key] == nil
, as th
Actually your test dictionary[key] == nil
can be used to check
if a key exists in a dictionary. It will not yield true
if the value
is set to nil
:
let dict : [String : Int?] = ["a" : 1, "b" : nil]
dict["a"] == nil // false, dict["a"] is .Some(.Some(1))
dict["b"] == nil // false !!, dict["b"] is .Some(.None)
dict["c"] == nil // true, dict["c"] is .None
To distinguish between "key is not present in dict" and "value for key is nil" you can do a nested optional assignment:
if let val = dict["key"] {
if let x = val {
println(x)
} else {
println("value is nil")
}
} else {
println("key is not present in dict")
}
Try this:
let value = dict[key] != nil
Hope it work for you. Thanks
As suggested here and above, the best solution is to use Dictionary.index(forKey:)
which returns Dictionary<Key, Value>.Index?
. Regardless of whether your value is an optional type, this returns an optional index, which if nil
, definitively tells you whether the key exists in the dictionary or not. This is much more efficient than using Dictionary.contains(where:)
which is documented to have "complexity O(n), where n is the length of the sequence."
So, a much better way to write .containsKey()
would be:
extension Dictionary {
func contains(key: Key) -> Bool {
self.index(forKey: key) != nil
}
}
I've been advised that dict.keys.contains() is actually O(1), so feel free to use it if you prefer.
You can always do:
let arrayOfKeys = dictionary.allKeys
if arrayOfKeys.containsObject(yourKey) {
}
else {
}
However I really dislike the idea of creating an NSDictionary which can contain optionals.
I handled it this way in Swift 4:
extension Dictionary {
func contains(key: Key) -> Bool {
let value = self.contains { (k,_) -> Bool in key == k }
return value
}
}
This uses Dictionary.contains(where: (key: Hashable, value: Value) throws -> Bool)
. By encapsulating it as an extension I have a good shot at updating the implementation to something better without modifying my code. I'm avoiding creating data, which index(forKey:Key)
does. I'm hoping it's more efficient than accessing keys
since that must create the whole array before searching it.
I believe the Dictionary type's indexForKey(key: Key)
is what you're looking for. It returns the index for a given key, but more importantly for your proposes, it returns nil if it can't find the specified key in the dictionary.
if dictionary.indexForKey("someKey") != nil {
// the key exists in the dictionary
}
Swift 3 syntax....
if dictionary.index(forKey: "someKey") == nil {
print("the key 'someKey' is NOT in the dictionary")
}