Dictionary .Add not supported C# - c#

I'm using a dictionary in my code as follows:
var allValues = new Dictionary<string, int>();
while (//condition))
{
response = // call to a method that returns some values of type Dictionary<string, int>
allValues.Add(response);
}
When I use .Add I get the following error:
What am I missing?

A Dictionary can be iterated over as collection of key/value pairs, so you can do this:
while (condition)
{
response = // call to a method that returns some values of type Dictionary<string, int>
foreach(KeyValuePair<string, int> kvp in response)
{
allValues.Add(kvp.Key, kvp.Value);
}
}
Assuming response is itself a Dictionary

You can add key value pair to dictionary. Try below code as an example.
var allValues = new Dictionary<string, int>();
int diccounter = 0;
while (true)
{
allValues.Add("a" + diccounter, diccounter++);
}

Related

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

How can I create a list of dictionaries as value of another dictionary?

I am trying to create a list of dictionaries as a value of another dictionary.
I basically want to store data like this
userPrivileges ["foo"]["a"] = 4;
userPrivileges ["foo"]["b"] = 8;
userPrivileges ["foo"]["c"] = 16;
userPrivileges ["bar"]["a"] = 4;
Here is what I tried
Dictionary<string, List<Dictionary<string, int>>> userPrivileges = new Dictionary<string, List<Dictionary<string, int>>>();
To add or update a key in the dictionary list I use the following method
protected void AddOrUpdateUserPrivilege(string moduleName, string key, int value)
{
if (!this.userPrivileges.ContainsKey(moduleName))
{
var entry = new Dictionary<string, int>(key, value);
this.userPrivileges.Add(moduleName, entry);
}
else
{
this.userPrivileges[moduleName][key] |= value;
}
}
Here is a screenshot of the syntax errors
How can I add a new entry to the main directory? and how can I access/update the value of a dictionary in the list?
Dictionaries don't have a constructor to insert elements. You can use the collection initializer syntax:
var entry = new Dictionary<string, int>
{
{ key, value }
};
Your other issues don't line up with the fact that you have a Dictionary<string, List<Dictionary<string, int>>>, because you're using it as Dictionary<string, Dictionary<string, int>>.
Since your code appears to make sense as the latter, I would suggest changing your definition to be:
Dictionary<string, Dictionary<string, int>> userPrivileges = new Dictionary<string, Dictionary<string, int>>();

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!

How to update the value stored in Dictionary in C#?

How to update value for a specific key in a dictionary Dictionary<string, int>?
Just point to the dictionary at given key and assign a new value:
myDictionary[myKey] = myNewValue;
It's possible by accessing the key as index
for example:
Dictionary<string, int> dictionary = new Dictionary<string, int>();
dictionary["test"] = 1;
dictionary["test"] += 1;
Console.WriteLine (dictionary["test"]); // will print 2
You can follow this approach:
void addOrUpdate(Dictionary<int, int> dic, int key, int newValue)
{
int val;
if (dic.TryGetValue(key, out val))
{
// yay, value exists!
dic[key] = val + newValue;
}
else
{
// darn, lets add the value
dic.Add(key, newValue);
}
}
The edge you get here is that you check and get the value of corresponding key in just 1 access to the dictionary.
If you use ContainsKey to check the existance and update the value using dic[key] = val + newValue; then you are accessing the dictionary twice.
Use LINQ: Access to dictionary for the key and change the value
Dictionary<string, int> dict = new Dictionary<string, int>();
dict = dict.ToDictionary(kvp => kvp.Key, kvp => kvp.Value + 1);
This simple check will do an upsert i.e update or create.
if(!dictionary.TryAdd(key, val))
{
dictionary[key] = val;
}
Here is a way to update by an index much like foo[x] = 9 where x is a key and 9 is the value
var views = new Dictionary<string, bool>();
foreach (var g in grantMasks)
{
string m = g.ToString();
for (int i = 0; i <= m.Length; i++)
{
views[views.ElementAt(i).Key] = m[i].Equals('1') ? true : false;
}
}
update - modify existent only. To avoid side effect of indexer use:
int val;
if (dic.TryGetValue(key, out val))
{
// key exist
dic[key] = val;
}
update or (add new if value doesn't exist in dic)
dic[key] = val;
for instance:
d["Two"] = 2; // adds to dictionary because "two" not already present
d["Two"] = 22; // updates dictionary because "two" is now present
This may work for you:
Scenario 1: primitive types
string keyToMatchInDict = "x";
int newValToAdd = 1;
Dictionary<string,int> dictToUpdate = new Dictionary<string,int>{"x",1};
if(!dictToUpdate.ContainsKey(keyToMatchInDict))
dictToUpdate.Add(keyToMatchInDict ,newValToAdd );
else
dictToUpdate[keyToMatchInDict] = newValToAdd; //or you can do operations such as ...dictToUpdate[keyToMatchInDict] += newValToAdd;
Scenario 2: The approach I used for a List as Value
int keyToMatch = 1;
AnyObject objInValueListToAdd = new AnyObject("something for the Ctor")
Dictionary<int,List<AnyObject> dictToUpdate = new Dictionary<int,List<AnyObject>(); //imagine this dict got initialized before with valid Keys and Values...
if(!dictToUpdate.ContainsKey(keyToMatch))
dictToUpdate.Add(keyToMatch,new List<AnyObject>{objInValueListToAdd});
else
dictToUpdate[keyToMatch] = objInValueListToAdd;
Hope it's useful for someone in need of help.
This extension method allows a match predicate delegate as the dictionary key selector, and a separate delegate to perform the dictionary value replacement, so it's completely open as to the type of key/value pair being used:
public static void UpdateAll<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, Func<TKey, TValue, bool> matchPredicate, Func<TValue, TValue> updatePredicate)
{
var keys = dictionary.Keys.Where(k => matchPredicate(k, dictionary[k])).ToList();
foreach (var key in keys)
{
dictionary[key] = updatePredicate(dictionary[key]);
}
}
Example usage:
Dictionary<int, string> dict = new Dictionary<int, string>();
dict.Add(1, "One");
dict.Add(2, "Two");
dict.Add(3, "Three");
//Before
foreach(var kvp in dict){
Console.WriteLine(kvp.Value);
}
dict.UpdateAll(
matchPredicate: (k, v) => k >= 2, //Update any dictionary value where the key is >= 2
updatePredicate: (v) => v = v + " is greater than One"
);
//After
foreach(var kvp in dict){
Console.WriteLine(kvp.Value);
}
You Can Also Use This Method :
Dictionary<int,int> myDic = new();
if (myDic.ContainsKey(1))
{
myDic[1] = 1234; // or use += to update it
}
Or By Value :
if (myDic.ContainsValue(1))
{
//do something ...
}

Categories