mawimawi
mawimawi

Reputation: 4333

How to initialize a dictionary containing lists of dictionaries?

I am starting to do a little development in C#, and I am stuck with a problem here. Usually I develop in Python where stuff like this is being implemented easily (at least for me), but I have no idea how to do that in C#:

I want to create a dictionary containing a list of dictionaries like the following using Generic Collections:

{ "alfred",  [ {"age", 20.0}, {"height_cm", 180.1} ],
  "barbara", [ {"age", 18.5}, {"height_cm", 167.3} ],
  "chris",   [ {"age", 39.0}, {"height_cm", 179.0} ]
}

I started with the following:

using System.Collections.Generic;
Dictionary<String, Dictionary<String, double>[]> persons;

But then I'd like to insert the three records from above at once into persons. I am stuck with syntax errors all the way.

Anyone have a solution for me?

Edit:

Thank you all - I didn't expect to receive so many well thought answers in such a short time! You are great!

Upvotes: 29

Views: 54278

Answers (3)

TheCodeKing
TheCodeKing

Reputation: 19220

You can easily do this:

 Dictionary<string, Dictionary<string, double>> dict =  
                       new Dictionary<string,Dictionary<string, double>>() {
     {"alfred",new Dictionary<string,double>() {{"age",20.0},{"height":180.1}}},
     {"barbara",new Dictionary<string,double>() {{"age",18.5},{"height": 167.3}}}
 };

You would be better off using typed person though, or an ExpandoObject to give typed syntax access to the dictionary.

Dictionary<string, Person> dict = new Dictionary<string,Person>() {
         {"alfred",new Person { age=20.0 ,height=180.1 }},
         {"barbara",new Person { age=18.5,height=167.3 }}
     };

Upvotes: 4

Caspar Kleijne
Caspar Kleijne

Reputation: 21864

IMHO the more elegant way to do this in c#, to avoid this use of the Dictionary, c# has better options than that,

is to create a class (or struct) like Person

public class Person 
{
    public Person() { }

    public string Name {get;set;}
    public int Age {get;set;}
    public double Height {get;set;}
}

and put those objects in a generic list or collection that implements IEnumerable

public List<Person>;

And use Linq to get the person you want

var personToLookfor =
    from p in people
    where p.Name == "somename"
    select p;

Upvotes: 1

Darin Dimitrov
Darin Dimitrov

Reputation: 1038710

You could use dictionary initializes. Not as elegant as Python, but could live with:

var persons = new Dictionary<string, Dictionary<string, double>>
{
    { "alfred", new Dictionary<string, double> { { "age", 20.0 }, { "height_cm", 180.1 } } },
    { "barbara", new Dictionary<string, double> { { "age", 18.5 }, { "height_cm", 167.3 } } },
    { "chris", new Dictionary<string, double> { { "age", 39.0 }, { "height_cm", 179.0 } } }
};

And then:

persons["alfred"]["age"];

Also notice that you need Dictionary<string, Dictionary<string, double>> for this structure and not Dictionary<string, Dictionary<string, double>[]>.

Also working with such structure could be a little PITA and harm readability and compile-time type safety of the code.

In .NET it is preferred to work with strongly typed objects, like this:

public class Person
{
    public double Age { get; set; }
    public string Name { get; set; }
    public double HeightCm { get; set; }
}

and then:

var persons = new[]
{
    new Person { Name = "alfred", Age = 20.0, HeightCm = 180.1 },
    new Person { Name = "barbara", Age = 18.5, HeightCm = 180.1 },
    new Person { Name = "chris", Age = 39.0, HeightCm = 179.0 },
};

and then you could use LINQ to fetch whatever information you need:

double barbarasAge = 
    (from p in persons
     where p.Name == "barbara"
     select p.Age).First();

To be noted of course that using collections would not be as fast as a hashtable lookup but depending on your needs in terms of performance you could also live with that.

Upvotes: 55

Related Questions