All the nested dictionaries holds the same value? - c#

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

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

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]],

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

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}]"))}]");
}

Related

Take count of repeating words in file

I have code to take count of repeating words in file
Here it is
static void Main()
{
StreamReader f = new StreamReader(#"d:\C#\text.txt");
string s = f.ReadToEnd();
char[] separators = { };//here is symbols
List<string> words = new List<string>(s.Split(separators));
Dictionary<string, int> map = new Dictionary<string, int>();
foreach (string w in words)
if (map.ContainsKey(w)) map[w]++; else map[w] = 1;
foreach (string w in map.Keys)
Console.WriteLine("{0}\t{l}", w.map[w]);
}
But in this row Console.WriteLine("{0}\t{l}", w.map[w]); I have this error.
Error CS1061 'string' does not contain a definition for 'map' and no extension method 'map' accepting a first argument of type 'string' could be found
How I can fix this error?
If I undertood what you wanted, this will help:
List<string> words = new List<string>() { "c#", "html", "web service", "c#", "c#" };
Dictionary<string, int> map = new Dictionary<string, int>();
foreach (string w in words)
{
if (map.ContainsKey(w))
{
map[w] = map[w]+1;
}
else
{
map[w] = 1;
}
}
//to iterate through Dictionary<string, int> use this instead
foreach (KeyValuePair<string, int> entry in map)
{
Console.WriteLine($"{entry.Key}\t{entry.Value}");
}

Loop through multiple dictionaries

I have 6 dictionaries. I want to compare another dictionaries against each one of them and see what dictionaries contains what strings. Is it possible to do with a foreach loop?
static Dictionary<string, int> d = new Dictionary<string, int>();
static Dictionary<string, double> dNL = new Dictionary<string, double>();
static Dictionary<string, double> dDE = new Dictionary<string, double>();
static Dictionary<string, double> dFR = new Dictionary<string, double>();
static Dictionary<string, double> dSP = new Dictionary<string, double>();
static Dictionary<string, double> dEN = new Dictionary<string, double>();
static Dictionary<string, double> dIT = new Dictionary<string, double>();
foreach (var f in d)
{
if (dNL.ContainsKey(f.Key))
{
//add to a numeric?
}
if (dDE.ContainsKey(f.Key))
{
//add to a numeric?
}
}
something like this?
what I currently have (and not working like intended):
// need to find a better solution
foreach (var f in d)
{
if (dNL.ContainsKey(f.Key))
{
dNLtotaal++;
}
}
foreach (var f in d)
{
if (dDE.ContainsKey(f.Key))
{
dDEtotaal++;
}
}
foreach (var f in d)
{
if (dFR.ContainsKey(f.Key))
{
dFRtotaal++;
}
}
foreach (var f in d)
{
if (dSP.ContainsKey(f.Key))
{
dSPtotaal++;
}
}
foreach (var f in d)
{
if (dEN.ContainsKey(f.Key))
{
dENtotaal++;
}
}
foreach (var f in d)
{
if (dIT.ContainsKey(f.Key))
{
dITtotaal++;
}
}
// NEED A MUCH BETTER SOLUTION
List<int> totaleD = new List<int>();
totaleD.Add(dNLtotaal);
totaleD.Add(dDEtotaal);
totaleD.Add(dFRtotaal);
totaleD.Add(dSPtotaal);
totaleD.Add(dENtotaal);
totaleD.Add(dITtotaal);
int max = !totaleD.Any() ? -1 : totaleD.Select((value, index) => new { Value = value, Index = index }).Aggregate((a, b) => (a.Value > b.Value) ? a : b).Index;
var maxIndex = totaleD.IndexOf(totaleD.Max());
Console.WriteLine(maxIndex);
You can do something like this:
var items = d.Keys;
var dictionaries = new[] { dNL, dDE, dFR, dSP, dEN, dIT };
var result = dictionaries.Select((d, index) =>
new {
Index = index,
Matches = items.Count(i => d.ContainsKey(i))
})
.OrderByDescending(i => i.Matches)
.Select(i => i.Index)
.FirstOrDefault();
Which gives you the index of the dictionary with the most matches
You could use lambda expressions to get the desired results. In following example, I tried to use two dictionaries:
int dNLtotaal = 0;
Dictionary<string, double> dNL = new Dictionary<string, double>();
Dictionary<string, double> dDE = new Dictionary<string, double>();
dNL.Keys.Where(k => dDE.ContainsKey(k)).ToList().ForEach(k => dNLtotaal++);
Hope it helps
Why not to have 1 Dictionary instead of 6? And keep there a pair [string, List[SomeObject]] where SomeObject is a class like
class SomeObject
{
public Enum Type;//dNL, dDE etc
public double Value;
}

How to retrieve all values in dictionary

I have the following Dictionary
public static Dictionary<string, List<int>> termDocumentIncidenceMatrix = new Dictionary<string, List<int>>();
I want to print all values in it , How i can make it ?
I found KeyValuePair but can't recognize in my program ?
Can anyone give me bit of code or link ?
foreach (var term in termDocumentIncidenceMatrix)
{
// Print the string (your key)
Console.WriteLine(term.Key);
// Print each int in the value
foreach (var i in term.Value)
{
Console.WriteLine(i);
}
}
If you want to print all values of the dictionary, you can use:
Dictionary<string, List<int>> dict = new Dictionary<string,List<int>>{{"A",new List<int>{1,2}},{"B",new List<int>{3,4}}};
var integersList = dict.Values.SelectMany(it => it);
foreach (var item in integersList)
{
Console.WriteLine(item);
}

Cannot implicitly convert 'System.Collections.Generic.Dictionary<string,System.Collections.Generic.List<string>>' to 'System...<string,string>'

class Program
{
static void Main(string[] args)
{
Dictionary<string, string> questionDict = new Dictionary<string, List<string>>(); //creating animal dict
List<string> removeKeys = new List<string>(); //so I can remove the keys if need be
questionDict.Add("Does it have whiskers?", "cat");
questionDict.Add("Does it purr?", "cat");
questionDict.Add("Does it bark?", "dog");
while (true)
{
foreach (KeyValuePair<string, string> kvp in questionDict)//checks for each value of kvp in questionDict
{
Console.WriteLine("Computer: {0}", kvp.Key); //prints kvp, or in this instance, the question
string userInput = Console.ReadLine();
if (userInput.ToLower() == "yes") //if yes THEN
{
Console.WriteLine("VAL: {0}", kvp.Value); //writes the value
}
else
{
removeKeys.Add(kvp.Key); //adds the wrong animals to the removeKeys list
}
}
foreach(string rKey in removeKeys)
{
questionDict.Remove(rKey); //removes all the values of rKey in removeKeys from questionDict
}
}
}
}
new Dictionary<string, List<string>>(); is giving me the error. Any help? I'm trying to make my dictionary have more than one value per key, which I am told can only be achieved through List<string>.
Change your declaration to:
Dictionary<string, List<string>> questionDict = new Dictionary<string, List<string>>();
The generic arguments of the variable being assigned to have to match those of what you are instantiating. The type also has to match of course (which it already did). Please make sure to make this correction to other applicable pieces of your code, like your foreach loop definition.
Note, if you like var (and even if you don't, this is one of the better places it can be used) you can just write:
var questionDict = new Dictionary<string, List<string>>();
Which is much shorter, and harder to mess up!

Dictionary<string, List<Tuple<string, int>>> dict_Info_A = new Dictionary<string,List<Tuple<string,int>>>();

I am using Dictionary with tuple as a parameter.
Dictionary<string, List<Tuple<string, int>>> dict_Info_A =
new Dictionary<string,List<Tuple<string,int>>>();
I am not able to initialize it ,complilation errors are coming.
Please suggest some way of initializing it.
Thanks in Advance!
This is how you'd use a collection initializer to initialize your dictionary:
Dictionary<string, List<Tuple<string, int>>> dict_Info_A = new Dictionary<string, List<Tuple<string, int>>>
{
{ "a", new List<Tuple<string, int>> { new Tuple<string, int>("1", 1) } }
{ "b", new List<Tuple<string, int>> { new Tuple<string, int>("2", 2) } }
};
I guess you should decide first, what dictionary you need
either mapping string to List<Tuple<string,int>>
or mapping string to Tuple<string,int>
With this line of code
dict_Info_A.Add("A", new Tuple<string,int>("hello", 1));
you're trying to use Dictionary<string, Tuple<string, int>>
Such dictionary should be initialized like this:
var dict_Info_A = new Dictionary<string, Tuple<string, int>>();
Here is the dictionary you showed in the original question:
Init the dictionary using var keyword:
//you can also omit explicit dictionary declaration and use var instead
var dict_Info_A = new Dictionary<string, List<Tuple<string, int>>>();
Init an element of the dictionary:
dict_Info_A["0"] = new List<Tuple<string, int>>();
Add elements to a list from the dictionary:
dict_Info_A["0"].Add(new Tuple<string, int>("asd", 1));
You can't use (comments):
dict_Info_A.Add("A", new Tuple<string,int>("hello", 1));
because the dictionary wants, as the value, a list. You could do something like:
List<Tuple<string,int>> list... // todo...
// for example: new List<Tuple<string, int>> { Tuple.Create("hello", 1) };
dict_Info_A.Add("A", list);
If you need multiple values per key, and want to append to this list then maybe:
List<Tuple<string,int>> list;
string key = "A";
if(!dict_Info_A.TryGetValue(key, out list)) {
list = new List<Tuple<string,int>>();
dict_Info_A.Add(key, list);
}
list.Add(Tuple.Create("hello", 1));

Categories