In Swift, a dictionary is nothing more than a collection of key-value pairs. In this post, I show you how to check if a dictionary contains a given key. Fire up Xcode and create a playground if you want to follow along with me.
We start with a clean slate. Add an import statement for Foundation and define a dictionary of type [String: String]
. The dictionary stores the birthdays of a handful of people. The keys are the names and the values are the birthdays.
import Foundation
let birthdays: [String: String] = [
"Emma": "12/12/1985",
"James": "11/07/1980",
"Cathy": "07/09/1990",
"Mike": "05/01/2000",
"Lucy": "11/03/1972"
]
We have a number of options to figure out if the dictionary contains a given key. Let's start simple. We ask the dictionary for its keys by accessing its keys
property. The keys
property returns an array of String
objects. To check if the dictionary contains a given key, we invoke the contains(_:)
method on the array of keys.
birthdays.keys.contains("Emma")
The contains(_:)
method can only be used if the array contains elements that conform to the Equatable
protocol.
If the elements of the array don't conform to the Equatable
protocol, then we can use the contains(where:)
method instead.
birthdays.keys.contains { key -> Bool in
key == "Emma"
}
We can simplify the implementation by using shorthand argument syntax.
birthdays.keys.contains { $0 == "Emma" }
The Swift Standard Library has another, more convenient method to check if a dictionary contains a given key. The Dictionary
type also defines a contains(where:)
method that is almost identical to that of the Array
type. It accepts a closure as its only argument. The closure accepts a key-value pair and its return type is Bool
. The contains(where:)
method returns true
if the closure that is passed to contains(where:)
returns true
for one of the dictionary's key-value pairs. Take a look at the following example.
birthdays.contains { key, value -> Bool in
key == "Emma"
}
The contains(where:)
method is convenient to verify if a given key exists. We can clean up the implementation by using shorthand argument syntax. Notice that the key-value pair is passed to the closure as a tuple.
birthdays.contains { $0.key == "Emma" }
We have one more option, but it isn't the most obvious one. Swift's Dictionary
type defines the index(forKey:)
method. Its return type is Dictionary.Index?
. A Dictionary.Index
object defines the position of a key-value pair in a dictionary.
We are not interested in the index, though. To verify if a given key exists, we check if the result of index(forKey:)
is equal to nil
. Remember that index(forKey:)
returns an optional value. Take a look at the updated example.
birthdays.index(forKey: "Emma") != nil
Let's end this tutorial with a convenient extension for Dictionary
that makes this task a little easier. We define a method on Dictionary
with name containsKey(_:)
.
extension Dictionary {
func containsKey(_ key: Key) -> Bool {
index(forKey: key) != nil
}
}
The method accepts a single argument of type Key
and returns a boolean. In the body of the method, we use the index(forKey:)
method to verify if the dictionary contains the given key. That's it. Using this convenience method is trivial as you can see below.
if birthdays.containsKey("Emma") {
print("yes")
} else {
print("no")
}