Click here to Skip to main content
Click here to Skip to main content

Transform a List To Dictionary of Lists

, 15 Jun 2014 CPOL
Rate this:
Please Sign up or sign in to vote.
How to transform a list to a dictionary in 3 different ways?

Introduction

I often need to search for a specific item inside a list, but as you know, the complexity of List.Find is O(n). So, if you englobe your find in a foreach loop, you might risk a serious performance decrease with an O(n²) algorithm.

What I prefer to do is, transform my list to a dictionary because the dictionary[key] is only O(1) thanks to indexing. You can manually transform dictionary to a list through code but .NET Framework provides us with more sophisticated ways today. Smile | :)

The ToDictionary Way

public Dictionary<string, string> TransformWithToDictionary()
{
    List<string> myList = new List<string>
    {
        "Brian",
        "Leslie",
        "Nathan",
        "Natalie",
        "Dimitry"
    };
    return myList.ToDictionary(k=>k);
}

Result will be a Dictionary<string, string> like this:

Dictionary<string, string> result = new Dictionary<string,string>
    {
        {"Brian", "Brian"},
        {"Leslie", "Leslie"},
        {"Nathan", "Nathan"},
        {"Natalie","Natalie"},
        {"Dimitry", "Dimitry"}
    };

ToDictionary method converts List to Dictionary while giving you the hand to choose the dictionary key (thanks to the lambda expression).

You need to be careful from raising an exception when you insert an already existing key such as this example:

return myList.ToDictionary(k=>k[0].ToString());

The expected result should be:

Dictionary<string, string> myList = new Dictionary<string,string>
    {
        {"B", "Brian"},
        {"L", "Leslie"},
        {"N", "Nathan"},
        {"N","Natalie"},
        {"D", "Dimitry"}
    };

But this can't be realized due to the duplicated "N" key and will eventually result in an exception saying: an element with the same key already exists in the dictionary.

The Lookup Way

public ILookup<string, string> TransformWithToLookup()
{
    List<string> myList = new List<string>
    {
        "Brian",
        "Leslie",
        "Nathan",
        "Nathan",
        "Dimitry"
    };
    return myList.ToLookup(k => k, v=>v[1].ToString());
}

The lookup mechanism is a bit different though:

  1. It groups values by keys inside a grouping
  2. It gives you the hand on what to retrieve from the value through a second lambda expression

The result can be accessed directly through keys:

List<string> tempRes = result["Brian"].ToList(); 
//should return List<string> { "r" }

Or iterated through:

foreach (var item in result)
{
    List<string> tempRes = item.ToList();
} 

Note that grouping can contain more than one value so if we do:

var temp = res2["Nathan"].ToList();

The expected result would be:

var temp = new List<string> { "a", "a" };

The Linq Way

public Dictionary<string, List<string>> TransformWithLinq()
{
    List<string> myList = new List<string>
    {
        "Brian",
        "Leslie",
        "Nathan",
        "Nathan",
        "Dimitry"
    };
    return myList.GroupBy(k => k, v => v).ToDictionary(g =>g.Key, g=>g.ToList());
}

This way is a combination of Linq methods, let's analyse them one by one:

  1. The GroupBy groups values by keys
  2. The GroupBy returns an IEnumerable of Groupings containing key and its corresponding values
  3. Using the ToDictionary way, we get a dictionary of { key, list of values} without worrying about duplicated keys !

Voila:

Dictionary<string, List<string>> result = new Dictionary<string, List<string>>
        {
            {"Brian", new List<string> {"Brian"}},
            {"Leslie", new List<string> {"Leslie"}},
            {"Nathan", new List<string> {"Nathan", "Nathan"}},
            {"Dimitry", new List<string> {"Dimitry"}},
        };

Credits

This tip aims to solve those tiny problems that we rarely care about. It may not be much for some people, but as a person looking to make my code as best as I can, it sure is a great way to save time and performance.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Bilel Msekni
Engineer
France France
I am a software engineer trying to improve his code quality through best practises and design patterns.
Follow on   LinkedIn

Comments and Discussions

 
GeneralMy vote of 5 PinprofessionalVolynsky Alex16-Jun-14 1:23 
QuestionThe title is better to include the keyword:transform Pinmemberleiyangge15-Jun-14 16:29 
AnswerRe: The title is better to include the keyword:transform PinprofessionalBilel Msekni16-Jun-14 10:05 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.141223.1 | Last Updated 15 Jun 2014
Article Copyright 2014 by Bilel Msekni
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid