Kresten
Kresten

Reputation: 838

All the nested dictionaries holds the same value?

I'm trying to build this datastructure with a nested dictionary:

["A",["A",123]],
["B",["B",123]],
["C",["C",123]],

And then loop over the data structure and print out the values.

The first problem is, that all the nested dictionaries are the same {"C",123}. I think it's because it is the same object, but I don't know how to overcome that. Can I dynamically create new objects in the loop ?

The other problem i face is in the loop where I try to print out the Values. The compiler says that it can't convert Dictionary to Dictionary.

using System;
using System.Collections.Generic;

namespace ConsoleApp1
{
    class Program
    {
        public static void Main()
        {
            List<string> liste = new() { "A", "B", "C" };
 
            Dictionary<string, Dictionary<string, int>> DictOfDicts = new();
            Dictionary<string, int> DictOfData = new();

            foreach (string i in liste)
            {
                DictOfData.Clear();
                DictOfData.Add(i, 123);
                DictOfDicts.Add(i, DictOfData);
            }
            foreach (Dictionary<string, int> i in DictOfDicts)
            {
                Console.WriteLine("Some result");
            }
        }
    }
}

Upvotes: 0

Views: 208

Answers (4)

Themelis
Themelis

Reputation: 4255

var liste = new List<string>() { "A", "B", "C" };
var DictOfDicts = new Dictionary<string, Dictionary<string, int>>();

foreach (var i in liste)
{
  // Create here a new DictOfData to add it to DicOfCicts.
  var DictOfData = new Dictionary<string, int>();
  DictOfData.Add(i, 123);
  DictOfDicts.Add(i, DictOfData);
}

The structure of DicOfDicts is,

["A",["A",123]],
["B",["B",123]],
["C",["C",123]],

Upvotes: 1

Rodrigo Rodrigues
Rodrigo Rodrigues

Reputation: 8576

You declared DictOfData outside of the foreach loop. Then, all the operations inside the loop are done on the same object. So, you are clearing and filling the same dictionary object over and over again, on each loop iteration.

Just move you declaration of DictOfData to inside the loop, and you'll be good to go.


Bonus:

The whole operation you displayed in the questions can be done with just this:

liste.ToDictionary(x => x, x => new Dictionary<string, int>() { { x, 123 } })

Upvotes: 2

Enigmativity
Enigmativity

Reputation: 117175

It's a very easy exercise to fix your code. Simply replace the DictOfData.Clear(); with the declaration of DictOfData itself. In other words, move the line Dictionary<string, int> DictOfData = new(); into the loop. That way you have a fresh instance of the nested dictionary rather than reusing the old one.

Try this code:

List<string> liste = new() { "A", "B", "C" };

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

foreach (string i in liste)
{
    Dictionary<string, int> DictOfData = new();
    DictOfData.Add(i, 123);
    DictOfDicts.Add(i, DictOfData);
}
foreach (KeyValuePair<string, Dictionary<string, int>> i in DictOfDicts)
{
    Console.WriteLine($"[{i.Key},{String.Join(",", i.Value.Select(x => $"[{x.Key},{x.Value}]"))}]");
}

Upvotes: 0

Jonas Hendrickx
Jonas Hendrickx

Reputation: 17

I've used a slightly older C# language specification for the answer, and made the type declarations more clear for you to understand.

List<string> list = new List<string>() { "A", "B", "C" };

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


foreach (string i in list)
{
    Dictionary<string, int> child = new Dictionary<string, int>();
    child.Add(i, 123);
    parent.Add(i, child);
}
foreach (KeyValuePair<string, Dictionary<string, int>> parentPair in parent)
{
    Dictionary<string, int> childDictionary = parentPair.Value;
    foreach (var childPair in childDictionary)
    {
        Console.WriteLine(childPair.Value);
    }
}

Upvotes: 0

Related Questions