web-dev-qa-db-fra.com

Comment initialiser un dictionnaire contenant des listes de dictionnaires?

Je commence à faire un petit développement en C #, et je suis coincé avec un problème ici. Habituellement, je développe en Python où des trucs comme celui-ci sont facilement implémentés (au moins pour moi), mais je ne sais pas comment faire cela en C #:

Je souhaite créer un dictionnaire contenant une liste de dictionnaires tels que les suivants à l'aide des collections génériques:

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

J'ai commencé par ce qui suit:

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

Mais ensuite, j'aimerais insérer les trois enregistrements d'en haut à la fois dans des personnes. Je suis coincé avec des erreurs de syntaxe tout le long.

Quelqu'un a une solution pour moi?

Modifier:

Merci à tous - je ne m'attendais pas à recevoir autant de réponses réfléchies en si peu de temps! Vous êtes formidable!

26
mawimawi

Vous pouvez utiliser le dictionnaire initialise . Pas aussi élégant que Python, mais pourrait vivre avec:

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 } } }
};

Puis:

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

Notez également que vous avez besoin de Dictionary<string, Dictionary<string, double>> pour cette structure et non Dictionary<string, Dictionary<string, double>[]>.

Travailler également avec une telle structure pourrait être un peu PITA et nuire à la lisibilité et à la sécurité de type au moment de la compilation du code.

Dans .NET, il est préférable de travailler avec des objets fortement typés, comme ceci:

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

puis:

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 },
};

puis vous pouvez utiliser LINQ pour récupérer toutes les informations dont vous avez besoin:

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

À noter bien sûr que l'utilisation de collections ne serait pas aussi rapide qu'une recherche de table de hachage mais qu'en fonction de vos besoins en termes de performances vous pourriez aussi vivre avec ça.

47
Darin Dimitrov

À mon humble avis, la façon la plus élégante de le faire en c #, pour éviter cette utilisation du dictionnaire , c # a de meilleures options que cela,

consiste à créer une classe (ou struct) comme Person

public class Person 
{
    public Person() { }

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

et mettre ces objets dans une liste générique ou une collection qui implémente IEnumerable

public List<Person>;

Et utilisez Linq pour obtenir la personne que vous voulez

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

Vous pouvez facilement le faire:

 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}}}
 };

Vous feriez mieux d'utiliser une personne tapée, ou un ExpandoObject pour donner accès à la syntaxe tapée au dictionnaire.

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 }}
     };
3
TheCodeKing