FAQ: Dictionaries - Accessing Values

This community-built FAQ covers the “Accessing Values” exercise from the lesson “Dictionaries”.

Paths and Courses
This exercise can be found in the following Codecademy content:

Learn Swift

FAQs on the exercise Accessing Values

There are currently no frequently asked questions associated with this exercise – that’s where you come in! You can contribute to this section by offering your own questions, answers, or clarifications on this exercise. Ask or answer a question by clicking reply (reply) below.

If you’ve had an “aha” moment about the concepts, formatting, syntax, or anything else with this exercise, consider sharing those insights! Teaching others and answering their questions is one of the best ways to learn and stay sharp.

Join the Discussion. Help a fellow learner on their journey.

Ask or answer a question about this exercise by clicking reply (reply) below!
You can also find further discussion and get answers to your questions over in Language Help.

Agree with a comment or answer? Like (like) to up-vote the contribution!

Need broader help or resources? Head to Language Help and Tips and Resources. If you are wanting feedback or inspiration for a project, check out Projects.

Looking for motivation to keep learning? Join our wider discussions in Community

Learn more about how to use this guide.

Found a bug? Report it online, or post in Bug Reporting

Have a question about your account or billing? Reach out to our customer support team!

None of the above? Find out where to ask other questions here!

If I have a dictionary - fully declared with key: value pairs, why does assigning any key to a new variable result in an Optional? That seems strange to me based on what I’ve learned until now.

This explanation seems incomplete and confusing to me:

If we tried to print the value of (appleScientific), we would get an output of:

Optional(“Pyrus malus”)

Swift returns an optional. […] For dictionaries, we might be trying to access a key that doesn’t exist, so as a precaution we first get an optional instead of getting the exact value. ← But why the precaution? We are not assigning a non-existing key out of thin air to a new variable. It’s a specific key that we know of, based on what we’ve declared before here:

var fruitNames = [
“mango”: “Mangifera indica”,
“banana”: “Musa paradisicum”,
“apple”: “Pyrus malus”
]

So when we take the key

fruitNames[“apple”]

and assign it to a new variable like so

var appleScientific = fruitNames[“apple”]

Why do I have to expect the compiler to give me an Optional? What’s the logic behind this? I mean, if I were to delete the key, the compiler could simply print out an error, but here they mention that it’s a precaution.

1 Like

Perhaps, it is undesirable to throw errors in some situations. Suppose, you have a dictionary storing a user’s data. Some of the data may be mandatory/required, whereas the presence/absence of some data is left to the user’s discretion. He/she may or may not choose to share some information.

In the case of essential data that absolutely must be present, we want errors to be thrown if that data is missing. However, other pieces of data may not be critical to our program. If they are available, that is good. If they are missing, that is fine. We don’t want errors to be thrown or for the program to crash.

You may get data from different sources other than declarations made explicitly by you. Or perhaps, you do declare and initialize a dictionary with the appropriate keys, but somewhere later in the code, some key(s) may be removed by some function/method. If a key is missing, you may want to customize how you handle that omission. Do you want to throw an error (essential data) or do you want to ignore the omission because the missing data is not critical? Optionals can give you flexibility to handle both situations.

Consider the example in which a user is required to share his/her name, but may share or omit the nickname.

var user1: [String: String] = [ "name": "Jack Weaver", "nickname": "Speedy" ]

var user2: [String: String] = [ "name": "Janet Flanagan" ]

for user in [user1, user2] {

  print("Name: \(user["name"]!)")

  if let nick = user["nickname"] {
      print("Nickname: \(nick)")
  }

  print()

}
# Output
Name: Jack Weaver
Nickname: Speedy

Name: Janet Flanagan

In this example, the name is mandatory. We don’t want complicated or verbose syntax to establish the absence/presence of the "name" key. We are going to proceed under the assumption that this key exists. If it is missing, an error will be thrown. This is desired, because we don’t want anonymous users. Force unwrapping of the optional allows us to do exactly this. All we need for forced unwrapping is !. That doesn’t overly complicate the syntax.

print(user["name"]!)

Suppose, trying to access a key of the dictionary didn’t result in an Optional. Instead, the value was returned directly. Absence of key would cause an error. That is satisfactory for the mandatory keys, but no so for the non-essential keys. We don’t want an error/crash when we try to access the "nickname" key. We could do something like:

if user.keys.contains("nickname") {
    print("Nickname: \(user["nickname"]!)")
}

This will work, but it will affect speed and efficiency of your program. The .keys method will create an array of the keys of the dictionary, and .contains will then traverse the array until either the key is found or you reach the end of the array. You may be adding and removing keys in various places in your program, so the keys of the dictionary aren’t fixed. Every time you want to check whether a key exists or not before accessing it, you will have to create an array of keys and then traverse it. The Optional avoids this issue.

if let nick = user["nickname"] {
    print("Nickname: \(nick)")
}

Instead of creating an array of keys and then searching through it, we simply go ahead and try to access the key. If the key is present in the dictionary, we can safely unwrap it as above. If the key is absent, the program doesn’t throw an error or crash.

If accessing the key of a dictionary directly returned the value associated with that key, then yes it will work nicely for the situations when we are absolutely sure that the key exists. But, for the non-essential keys, trying to directly return a value would cause an error, and we would have to use something like user.keys.contains("nickname") to avoid this with consequences for speed and efficiency.

The Optional offers us a nice balance. If the key is guaranteed to be present, then simply adding a ! allows us to unwrap the optional without much hassle. If the key may or may not be present, then an Optional doesn’t cause an error and allows us to safely unwrap it (if it is present) or do something else (if it is absent) without adverse effects on speed or efficiency.

1 Like

Brilliantly put! I’m impressed by your comment. Thank you so much for taking the time to clarify the logic behind the concept! I think, if the entire chapter on dictionaries was based on your analogy of a, let’s say “address book”, I would have immediately grasped the idea. Every person has a name but they don’t always have a nickname. Makes total sense. Now that this knot is solved, I think it’s easy to comprehend why there is “pay” initially to the concept itself.

In the current version of the lesson, a “fruit stand” is our point of reference. Which does not translate well into the abstract concept of hierarchy of literals and optionals. There is no mention of it being a fruit stand that always has crates for a particular group of fruits but not always receives deliveries of those fruits. But that’s an important detail. If that information is missing, to be expected to just be mindful of the fact that “it’s a precaution” can be confusing.