Dictionaries

Pairing Keys with Values

What is it?

A Dictionary is a construct that allows us to pair keys and values. Dictionaries are sometimes referred to as hashtables or maps.

Let's say that I have the following student information:

Student ID Name
23052 Harvey Dent
68929 Jessica Jones
57285 J Jonah Jameson

Each student will have a unique ID, but multiple students could have the same name.


How Do I…?

Each student ID (key) corresponds to a student name (value). Each of these entries are known as a KeyValuePair entry. A Dictionary holds all of these KeyValuePair entries and gives us convenient methods to work with them. (State and behavior again!)

key
↓↓↓

Student ID
value
↓↓↓↓↓

Name
23A52 Harvey Dent
68Z29 Jessica Jones
57W85 J Jonah Jameson

Dictionary is a generic type, so we declare it, specifying the types for key and value:

Dictionary<int, string> students =
  new Dictionary<int, string>();

The first type parameter indicates the type of the key. Student IDs are ints.

Dictionary<int, string> students;

The second indicates the type of the value. Student names are strings.

Dictionary<int,string> students;

…build it?

Dictionary is an object, so in order to instantiate (create) a dictionary, we must call the constructor for it.

Dictionary<int, string> students = new Dictionary<int, string>();

To add students, we use Add(key, value):

students.Add("23052", "Harvey Dent");
students.Add("68929", "Jessica Jones");
students.Add("57285", "J Jonah Jameson");

Let's look at what we've got:

Console.WriteLine("The students are " + students);

What is it Good For?

We know that we could use an Array or a List to hold collections of things, so why Dictionary?

Imagine we wanted to look up students by name from our example student information.


First, we'd need to create a class to hold student ID and name:

class Student
{
    public int ID { get; set; }
    public string Name { get; set; }

    public Student(int id, string name)
    {
        ID = id;
        Name = name;
    }
}

Here, we have populated a collection of Student objects, to find a student by ID. To find a student, we'd do something like this:

List<Student> studentList = new List<Student>()
{
    new Student(id: 1001, name: "John"),
    new Student(id: 1002, name: "Mary")
};// Using id and name are optional.
  // here we're making the code more expressive.

foreach (var student in studentList)
{
    if (student.ID == 1002)
    {
      Console.WriteLine(student.Name); // Mary
    }
}

Dictionaries make this easier. Also, what if there were 20,000 students and the one we were looking for was 19,998th in our list? Maps also perform better for doing lookups like this.


Finding our Student

Here, we have populated a Dictionary named studentDictionary whose keys are IDs (ints) and whose values are student names (strings), finding a student by ID with a Dictionary is simple:

Dictionary<int, string> studentDictionary = new Dictionary<int, string>();

studentDictionary.Add(1001, "John");
StudentDictionary.Add(1002, "Mary");

var student = studentDictionary[1002];
Console.WriteLine(student.Name);

A Collection of Collections

Dictionaries are part of the Systems.Collections.Generic namespace. A dictionary is a collection of Key and Value pairs. Each Key must uniquely identify each Value in the dictionary.

As an example, we might have a Dictionary whose Keys are social security numbers and whose values are their names. We may have two "John Smith"s, but we would never have two John Smiths with the same SSN.

Your Social Security Number is a Key that uniquely identifies you, much like a Dictionary's Key identifies an object.

Dictionary keys can not be duplicated and we don't care about their order, so we use a Set to represent them. This allows us to retrieve data easily.

Dictionary values can be duplicated, but their order isn't significant. This allows us to have things that could be named the same, in the same Dictionary.


Looking at Keys

To look at a Dictionary's keys, we call its Keys property:

foreach(var student in studentDictionary)
{
    Console.Writeline("The student IDs are " + student.Key);
}
//using our loop we iterate over the keys in our Dictionary and return the Keys

Looking at Values

To look at a Dictionary's values, we call its Values (Surprise!) property:

foreach(var student in studentDictionary)
{
    Console.Writeline("The student IDs are " + student.Value);
}
//using our loop we iterate over the keys in our Dictionary and return the Keys

Looking at Entries

If we want to iterate over all (or many) of the entries in a map, looking at both key and value, it is intuitive to do something like this:

foreach(var key in studentDictionary.Keys)
{
    Console.WriteLine("The student IDs are " + key);
}

foreach(var student in studentDictionary)
{
    Console.WriteLine("The student IDs are " + student.Key);
}

Useful Dictionary Properties

property what does it do?
Item[key] gets or sets the value associated with the key
Count returns the number of entries in the map


Other Useful Dictionary Methods

method what does it do?
Add(key, value) adds the entry with key and value
Remove(key) removes the entry associated with key
ContainsKey(key) returns true if this map contains the key
ContainsValue(value) returns true if this map contains the value
Clear() removes all entries from the map