Click here to Skip to main content
15,860,859 members
Articles / Programming Languages / C#
Tip/Trick

Transform a List To Dictionary of Lists

Rate me:
Please Sign up or sign in to vote.
4.71/5 (6 votes)
15 Jun 2014CPOL2 min read 32.5K   93   11   3
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. :)

The ToDictionary Way

C#
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:

C#
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:

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

The expected result should be:

C#
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

C#
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:

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

Or iterated through:

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

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

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

The expected result would be:

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

The Linq Way

C#
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:

C#
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)


Written By
Engineer
France France
Living by this code ".. Technology was created to provide solutions ..", i'm a challenge lover, discipline enforcer and a team player. Above all, i'm a software engineer who likes to solve problems through technology.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Volynsky Alex16-Jun-14 0:23
professionalVolynsky Alex16-Jun-14 0:23 
QuestionThe title is better to include the keyword:transform Pin
leiyangge15-Jun-14 15:29
leiyangge15-Jun-14 15:29 
AnswerRe: The title is better to include the keyword:transform Pin
Bilel Msekni16-Jun-14 9:05
professionalBilel Msekni16-Jun-14 9:05 

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

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