Dictionary With One To Many Relationship

Dictionary With One To Many Relationship Banner Image

Introduction

While a dictionary has a set struture and use cases for the one to one relationship. You may be wondering how you can use a dictionary or List for a one to many relationship with the data. There are two and possible more ways. But I'm going to be talking how to do it with a dictionary and a list in this article.

Can A Dictionary Have Duplicate Keys?

A dictionary can not have duplicate keys, because the keys are required to be unique. Usually a dictionary has one to one ratio to the key and values. But in this case we want to have a one key and many values. There are a few work arounds. Let's look at the first example.

Summary Table

Analysis TypeDictionary with ListList with KeyValuePairs
Use CaseSpeed of key retrievalSorting of keys
PerformanceValue Set Approaches O(1) then lookup for Value O(1)O(N)

Dictionary and List Method

The idea behind this is to still have a quick look up by the key values. You can add key and value to the dictionary like the following below. This code has a class named Data which stores a master name and one of it's synonyms. The name will stay the same while the synonym will be changing so this is a one to many relationship.

Dictionary<string,List<string>> synonymsDictionary = new Dictionary<string,List<string>>();
List<Data> dataList = new List<Data>();
dataList.Add(new Data("Euphoric", "Exultant"));//Generate Data point
dataList.Add(new Data("Euphoric", "Rapturous"));//Generate Data point
dataList.Add(new Data("Euphoric", "Thrilled"));//Generate Data point
dataList.Add(new Data("Euphoric", "Transported"));//Generate Data point
dataList.Add(new Data("Euphoric", "Delirious"));//Generate Data point

foreach (Data item in dataList)//Loop through all data points
{
    if(!synonymsDictionary.ContainsKey(item.Name))//Check if the key is in the dictionary then take appropriate action
    {
        synonymsDictionary[item.Name] = new List<string>();//If key does not exist then add the key with a new list
        Console.WriteLine($"New List Added for name:{item.Name}");
        synonymsDictionary[item.Name].Add(item.Synonym);//Add the value to the new list
        Console.WriteLine($"Synonym Added:{item.Synonym}");
    }
    else
    {
        synonymsDictionary[item.Name].Add(item.Synonym);//If key already exists then just add to the list
        Console.WriteLine($"Synonym Added:{item.Synonym}");
    }
}

class Data
{
    public Data(string name, string synonym)
    {
        Name = name;
        this.Synonym = synonym;
    }

    public string Name { get; set; }
    public string Synonym { get; set; }
}
Code Output
New List Added for name:Euphoric
Synonym Added:Exultant
Synonym Added:Rapturous
Synonym Added:Thrilled
Synonym Added:Transported
Synonym Added:Delirious

Dictionary and List Code Example

This example code shows how you can get the values from the dictionary after they're already there. This is a dictionary where the key is the main word and the values are the synonyms.

Dictionary<string, List<string>> synonymsDictionary = new Dictionary<string, List<string>>()
{
    { "Gleeful", new List<string>{ "Joyful", "Delighted", "Ecstatic", "Elated", "Enchanted" } },
    { "Cheerful", new List<string>{ "Glad", "Pleased", "Jubilant", "Radiant", "Satisfied" } },
    { "Content", new List<string>{ "Fulfilled", "Satisfied", "Happy", "Gratified", "Pleased" } },
    { "Jovial", new List<string>{ "Merry", "Festive", "Jolly", "Convivial", "Lighthearted" } }}
};//Generate dictionary with one key but many values

string key = "Content";
if (synonymsDictionary.TryGetValue(key, out List<string> values))//Get the list of values from the dictionary with one key
{
    foreach (string value in values)//Loop through all the values
    {
        Console.WriteLine($"value:{value}");//Print out values
    }
}
Code Output
value:Fulfilled
value:Satisfied
value:Happy
value:Gratified
value:Pleased

List Of KeyValuePairs

While the dictionary uses the KeyValuePair to store they keys and values internally. We can use the KeyValuePair class outside of the dictionary context. Instead of a lookup through the key to get the values. We can sort this list or search through it to find the key value pair that we want.

List Of KeyValuePairs Example Code

List<KeyValuePair<string, string>> synonymsList = new List<KeyValuePair<string, string>>()
{
    new KeyValuePair<string, string>("Large", "Big"),
    new KeyValuePair<string, string>("Large", "Huge"),
    new KeyValuePair<string, string>("Large", "Enormous"),
    new KeyValuePair<string, string>("Large", "Gigantic"),
    new KeyValuePair<string, string>("Large", "Immense"),

    new KeyValuePair<string, string>("Small", "Little"),
    new KeyValuePair<string, string>("Small", "Tiny"),
    new KeyValuePair<string, string>("Small", "Miniature"),
    new KeyValuePair<string, string>("Small", "Petite"),
    new KeyValuePair<string, string>("Small", "Diminutive"),

    new KeyValuePair<string, string>("Bright", "Radiant"),
    new KeyValuePair<string, string>("Bright", "Vibrant"),
    new KeyValuePair<string, string>("Bright", "Luminous"),
    new KeyValuePair<string, string>("Bright", "Shiny"),
    new KeyValuePair<string, string>("Bright", "Dazzling"),

    new KeyValuePair<string, string>("Dark", "Gloomy"),
    new KeyValuePair<string, string>("Dark", "Shadowy"),
    new KeyValuePair<string, string>("Dark", "Obscure"),
    new KeyValuePair<string, string>("Dark", "Dim"),
    new KeyValuePair<string, string>("Dark", "Murky"),

    new KeyValuePair<string, string>("Fast", "Quick"),
    new KeyValuePair<string, string>("Fast", "Rapid"),
    new KeyValuePair<string, string>("Fast", "Swift"),
    new KeyValuePair<string, string>("Fast", "Speedy"),
    new KeyValuePair<string, string>("Fast", "Expeditious")
};//Generate a list of KeyValuePairs

foreach (KeyValuePair<string, string> keyValuePair in synonymsList)//Loop through all the KeyValuePairs
{
    Console.WriteLine($"value:{keyValuePair.Value}");//Print out values
}
Code Output
value:Miniature
value:Petite
value:Diminutive
value:Radiant
value:Vibrant
value:Luminous
value:Shiny
value:Dazzling
value:Gloomy
value:Shadowy
value:Obscure
value:Dim
value:Murky
value:Quick
value:Rapid
value:Swift
value:Speedy
value:Expeditious

Conclusion

Having a dictionary with key then a list is a solid choice to solve the one key to many values problem. It has a fast lookup and usually there are not many values to search through after that. This can help divide the data up in to more manageable chucks.

Using the list to store the KeyValuePairs is also an option. This give the opportunity to sorting and displaying the data in different ways or order. So you'll need to choose carefully depending on the requirements that are needed.

Know any other collections or way to have a collection or data structure that has a one to many relationship? Let me know in the comments below.

Get Latest Updates
Comments Section