'Determining if Swift dictionary contains key and obtaining any of its values
I am currently using the following (clumsy) pieces of code for determining if a (non-empty) Swift dictionary contains a given key and for obtaining one (any) value from the same dictionary.
How can one put this more elegantly in Swift?
// excerpt from method that determines if dict contains key
if let _ = dict[key] {
return true
}
else {
return false
}
// excerpt from method that obtains first value from dict
for (_, value) in dict {
return value
}
Solution 1:[1]
Why not simply check for dict.keys.contains(key)?
Checking for dict[key] != nil will not work in cases where the value is nil.
As with a dictionary [String: String?] for example.
Solution 2:[2]
The accepted answer let keyExists = dict[key] != nil will not work if the Dictionary contains the key but has a value of nil.
If you want to be sure the Dictionary does not contain the key at all use this (tested in Swift 4).
if dict.keys.contains(key) {
// contains key
} else {
// does not contain key
}
Solution 3:[3]
Looks like you got what you need from @matt, but if you want a quick way to get a value for a key, or just the first value if that key doesn’t exist:
extension Dictionary {
func keyedOrFirstValue(key: Key) -> Value? {
// if key not found, replace the nil with
// the first element of the values collection
return self[key] ?? first(self.values)
// note, this is still an optional (because the
// dictionary could be empty)
}
}
let d = ["one":"red", "two":"blue"]
d.keyedOrFirstValue("one") // {Some "red"}
d.keyedOrFirstValue("two") // {Some "blue"}
d.keyedOrFirstValue("three") // {Some "red”}
Note, no guarantees what you'll actually get as the first value, it just happens in this case to return “red”.
Solution 4:[4]
My solution for a cache implementation that stores optional NSAttributedString:
public static var attributedMessageTextCache = [String: NSAttributedString?]()
if attributedMessageTextCache.index(forKey: "key") != nil
{
if let attributedMessageText = TextChatCache.attributedMessageTextCache["key"]
{
return attributedMessageText
}
return nil
}
TextChatCache.attributedMessageTextCache["key"] = .some(.none)
return nil
Solution 5:[5]
If you want to return the value of the key you can use this extension
extension Dictionary {
func containsKey(_ key: Key) -> Value? {
if let index = index(forKey: key){
return self.values[index]
}
return nil
}
}
Solution 6:[6]
if dictionayTemp["quantity"] != nil
{
//write your code
}
Solution 7:[7]
If you are dealing with dictionary that may contain nil value for a key then you can check existence of key by:
dictionay.index(forKey: item.key) != nil
For getting first value in dictionary:
dictionay.first?.value // optional since dictionary might be empty
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Hans Terje Bakke |
| Solution 2 | bergy |
| Solution 3 | Airspeed Velocity |
| Solution 4 | |
| Solution 5 | Rashid Latif |
| Solution 6 | Paresh Hirpara |
| Solution 7 | Soumya Mahunt |
