4
votes

c # lire des lignes et stocker des valeurs dans des dictionnaires

Je veux lire un fichier csv et stocker les valeurs de manière correcte dans des dictionnaires.

    g.add_vertex("0", new Dictionary<string, int>() { { "1", 731 } , 
{ "2", 1623 } , { "3" , 1813 } , { "4" , 2286 } , { "5" , 2358 } ,
{ "6" , 1 } , ... });

la fonction add_vertex ressemble à ceci:

Dictionary<string, Dictionary<string, int>> vertices = new Dictionary<string, Dictionary<string, int>>();

    public void add_vertex(string name, Dictionary<string, int> edges)
    {
        vertices[name] = edges;
    }

Le fichier csv ressemble à ceci:

entrez description de l'image ici

il y a plusieurs lignes avec les mêmes valeurs [0] (par exemple, les valeurs [0] est" 0 ") et au lieu d'écraser le dictionnaire existant, il faut l'ajouter au dictionnaire qui existe déjà avec les valeurs [0] = 0. comme ceci:

using (var reader = new StreamReader(@"CSV_testdaten.csv"))
{
    while (!reader.EndOfStream)
    {
        string new_line;
        while ((new_line = reader.ReadLine()) != null)
        {
            var values = new_line.Split(",");               
            g.add_vertex(values[0], new Dictionary<string, int>() { { values[1], Int32.Parse(values[2]) } });
        }
    }
}

Je veux ajouter toutes les valeurs qui ont le même ID (dans la première colonne du csv) dans un dictionnaire avec cet ID. Mais je ne sais pas comment faire ça. Quelqu'un peut-il aider?


1 commentaires

Si votre méthode add_vertex (qui serait plus conventionnellement appelée AddVertex , au fait - c'est une bonne idée de prendre l'habitude de suivre tôt les conventions de dénomination) ne doit accepter un seul bord, pourquoi ne pas le changer en AddVertex (string name, string edgeName, int edgeValue) ? (Je viens de deviner les noms des paramètres - je ne peux pas dire ce que les arêtes sont censées représenter.) Ensuite, vérifiez simplement si le dictionnaire contient déjà une entrée pour ce nom de sommet et créez une nouvelle valeur (également un dictionnaire) si non. Dans tous les cas, ajoutez la nouvelle entrée au dictionnaire pour ce sommet.


3 Réponses :


2
votes

Lorsque nous avons des données complexes et que nous voulons les interroger , Linq peut être très utile:

var records = File
  .ReadLines(@"CSV_testdaten.csv")
  .Where(line => !string.IsNullOrWhiteSpace(line)) // to be on the safe side
  .Select(line => line.Split(','))
  .Select(items => new {
     vertex = items[0],
     key    = items[1],  
     value  = int.Parse(items[2])  
   })
  .GroupBy(item => item.vertex)
  .Select(chunk => new {
     vertex = chunk.Key,
     dict   = chunk.ToDictionary(item => item.key, item => item.value)
  });

foreach (var record in records)
  g.add_vertex(record.vertex, record.dict);


1 commentaires

cela fonctionne parfaitement pour moi. Je vous remercie! pour une raison quelconque, j'ai dû diviser la ligne dans le csv sur (";") mais tout le reste fonctionne très bien. Merci :)



1
votes

Vous pouvez diviser votre code en deux parties. Le premier lira les lignes csv:

var result = ReadCsvLines()
    .ToArray()
    .GroupBy(x => x.Item1)
    .ToDictionary(x => x.Key, x => x.ToDictionary(t => t.Item2, t => int.Parse(t.Item3)));

et le second ajoutera ces lignes au dictionnaire:

public static IEnumerable<(string, string, string)> ReadCsvLines()
{
    using (var reader = new StreamReader(@"CSV_testdaten.csv"))
    {
        while (!reader.EndOfStream)
        {
            string newLine;
            while ((newLine = reader.ReadLine()) != null)
            {
                var values = newLine.Split(',');

                yield return (values[0], values[1], values[2]);
            }
        }
    }
}

Avec votre entrée résultat code> serait:

 entrez la description de l'image ici


0 commentaires

2
votes

Cela fonctionne-t-il pour vous?

vertices =
    File
        .ReadLines(@"CSV_testdaten.csv")
        .Select(x => x.Split(','))
        .Select(x => new { vertex = x[0], name = x[1], value = int.Parse(x[2]) })
        .GroupBy(x => x.vertex)
        .ToDictionary(x => x.Key, x => x.ToDictionary(y => y.name, y => y.value));


0 commentaires