convert dictionary to list of objects in C#

I have a dictionary:

Dictionary<string, string> valuesDict = new Dictionary<string, string> {
    {“Q1”, “A1”},
    {“Q2”, “A2”},
    {“Q3”, “A3”},
    {“Q4”, “A4”} /*20000 Q and A pairs*/
};

Inorder to load this to a third party interface which only accepts a list of objects (of class QuestionAnswer), I am manually converting it to a list like so

Public Class QuestionAnswer {
    Public string Question;
    Public string Answer;
}

objects of the QuestionAnswer class are then created within the loop

List<QuestionAnswer> qaList = new List<QuestionAnswer>();
foreach(var key in valuesDict.Keys) {
    qaList.add(new QuestionAnswer {Question = key, Answer = valuesDict[key]});
}

I want to know if there is a faster way to populate this list from the dictionary.

What I have found so far: While looking around for the solution, I came across a solution for a conversion of simple Dictionary to List of simple types like so: Convert dictionary to List<KeyValuePair> Could someone please help me in utilizing this solution to my case please. I am also open to any other solution that can remove this overhead.

Upvotes: 5

Views: 17993

Answers (4)

Fruchtzwerg
Fruchtzwerg

Reputation: 11389

Basically ther are two common approaches. Using a foreach or LINQ. To check the performance you can use a stopwatch and run a simple code like this:

Dictionary<string, string> valuesDict = new Dictionary<string, string>();
for (uint i = 0; i < 60000; i++)
{
    valuesDict.Add(i.ToString(), i.ToString());
}

List<QuestionAnswer> qaList;
Stopwatch stp = new Stopwatch();

stp.Start();
//LINQ approach
qaList = valuesDict.Select(kv => new QuestionAnswer { Question = kv.Key, Answer = kv.Value }).ToList();
stp.Stop();
Console.WriteLine(stp.ElapsedTicks);

stp.Restart();
//Foreach approach
qaList = new List<QuestionAnswer>();
foreach (var item in valuesDict)
{
    qaList.Add(new QuestionAnswer { Question = item.Key, Answer = item.Value });
}
stp.Stop();
Console.WriteLine(stp.ElapsedTicks);

My result: Foreach performes about 30% faster than the LINQ approach.

Upvotes: 1

InBetween
InBetween

Reputation: 32740

Faster? Well, yes, absolutely, iterate directly the dictionary, not the Keys collection:

foreach(var kv in valuesDicts) {
    qaList.add(new QuestionAnswer {Question = kv.Key, Answer = kv.Value});

Or better yet, using System.Linq:

valuesDict.Select(kv => new QuestionAnswer(kv.Key, kv.Value);

In your code you are performing an unecessary key search on each iteration.

Upvotes: 0

Zein Makki
Zein Makki

Reputation: 30022

You're doing an unnecessary lookup for the key:

foreach(var item in valuesDict) {
    qaList.add(new QuestionAnswer {Question = item.Key, Answer = item.Value});
}

You can also provide the list count when intializing to avoid resize:

List<QuestionAnswer> qaList = new List<QuestionAnswer>(valuesDict.Keys.Count);

You can use LinQ-based solutions, but that is slower and you're asking for optimal solution.

Upvotes: 8

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236188

You can create a list with LINQ by projecting each KeyValuePair of the dictionary into your QuestionAnswer object:

 var qaList = 
    valuesDict.Select(kvp => new QuestionAnswer { Question = kvp.Key, Answer = kvp.Value })
              .ToList()

Upvotes: 7

Related Questions