how to use this definition in c# with dictionaries - c#

GROUP["10"]["MATH"] = 30;
GROUP["11"]["MATH"] = 40;
GROUP["9"]["CHEM"] = 50;
...
Can u tell me how to use it with dictionaries. How to define a dictionary for this example?

Dictionary<string,Dictionary<string,int>>
The first [] returns a dictionary, and the second [] operates on that dictionary and returns an int

Dictionary<string, Dictionary<string, int>>
Use:
Dictionary<string, Dictionary<string, int>> dic = new Dictionary<string, Dictionary<string, int>>();
Dictionary<string, int> inner = new Dictionary<string, int>();
inner.Add("MATH", 30);
dic.Add("10", inner);
...
Access
dic["10"]["MATH"]

use this one ......
Dictionary<string,Dictionary<string,int>>
pls go through this link for more info ....On dictionaries,if you are new to dictionaries..
http://msdn.microsoft.com/en-us/library/xfhwa508.aspx

You could create a Dictionary<Tuple<string, string>, int> but you may better defining a class/ custom collection to better represent this, it depends on what your use case is.
An example of Dictionary<Tuple<string, string>, int>
var dict = new Dictionary<Tuple<string, string>, int>
{
{ new Tuple<string,string>("10", "MATH"), 30 },
{ new Tuple<string,string>("11", "MATH"), 40 },
{ new Tuple<string,string>("9", "CHEM"), 50 }
};

Option 1: Use a Dictionary<string, Dictionary<string, int>>.
Dictionary<string, int> group10 = new Dictionary<string, int>();
group10.Add("MATH", 30);
Dictionary<string, int> group11 = new Dictionary<string, int>();
group10.Add("MATH", 40);
Dictionary<string, int> group9 = new Dictionary<string, int>();
group10.Add("CHEM", 50);
var group = new Dictionary<string, Dictionary<string, int>>();
group.Add("10", group10);
group.Add("11", group11);
group.Add("9", group9);
int v1 = group["10"]["MATH"]; // v1 = 30
int v2 = group["11"]["MATH"]; // v2 = 40
int v3 = group["9"]["CHEM"]; // v3 = 50
Option 2: Or create a compound key for the dictionary that overrides GetHashCode and Equals, or you could use Tuple.
var group = new Dictionary<Tuple<string, string>, int>();
group.Add(Tuple.Create("10", "MATH"), 30);
group.Add(Tuple.Create("11", "MATH"), 40);
group.Add(Tuple.Create("9", "CHEM"), 50);
int v1 = group[Tuple.Create("10", "MATH")]; // v1 = 30
int v2 = group[Tuple.Create("11", "MATH")]; // v2 = 40
int v3 = group[Tuple.Create("9", "CHEM")]; // v3 = 50
If using Option 1 you must remember to create the second level Dictionary<string, int>, before adding the integer values.

Something like this may be
Dictionary<string, Dictionary<string><int>> dict = new Dictionary<string, Dictionary<string><int>>();

You could also create your own dictionary:
public class GroupDict
{
const string Separator = ";";
Dictionary<string, int> _internalDict = new Dictionary<string, int>();
public void Add(string key1, string key2, int value)
{
_internalDict.Add(key1 + Separator + key2, value);
}
public int this[string key1, string key2]
{
get { return _internalDict[key1 + Separator + key2]; }
set { _internalDict[key1 + Separator + key2] = value; }
}
public int Count
{
get { return _internalDict.Count; }
}
}
You can then use it like:
GroupDict groups = new GroupDict();
groups.Add("10", "MATH", 30);
// OR
groups["10", "MATH"] = 30;
Console.WriteLine(groups["10", "MATH"]);

Also note that you can't create a Multi-Key Dictionary in C#.
You will need your own struct for that.

Related

How to port a multi-keys hash from perl to a c# equivalent?

While porting a perl module into c# code, I stumbled into how to port a multi-keys hash from perl to a c# equivalent:
$map{$key1}{$key2}=$value;
In the perl code to port, I can define multiple lines with the same key1, and also I can access the hash only with the first key:
# define multiple lines with the same key1 : ex :
$key1 = '1';
$key2 = 'a';
$map{$key1}{$key2}=54;
$key2 = 'b';
$map{$key1}{$key2}=47;
# can access the hash only with the first key : ex :
if (exists($$map{'1'}) {}
But in c# if I use a c# dictionary, I can not add a same key1 lines, it says duplicate keys. For example, in c#, if I do this, I have an error:
var map = new Dictionary<string, Dictionary<string, int>>();
map.Add(key1, new Dictionary<string, int>() { { key2, 54 } });
map.Add(key1, new Dictionary<string, int>() { { key2, 47 } });
Same wise, if I use a tuple as the key, I will be able to add 2 rows with the same key1 (and a different key2), but I will not be able to access the dictionary only with the first key:
var map = new Dictionary<Tuple<string, string>, int>();
map.Add(new Tuple<string, string>(key1, key2), 54);
map.Add(new Tuple<string, string>(key1, key2), 47);
if (map["1"] != null) {} // => this gives an error
Any idea?
In your root dictionary, you have to add a new entry only if it doesn't exist already. Try this:
key1 = "1";
key2 = "a";
if(!map.TryGetValue(key1, out var subMap))
{
map[key1] = subMap = new Dictionary<string, int>();
}
subMap[key2] = 54;
// somewhere else in code
key1 = "1";
key2 = "b";
if(!map.TryGetValue(key1, out var subMap))
{
map[key1] = subMap = new Dictionary<string, int>();
}
subMap[key2] = 47;

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

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

How to Compare Values of Two Dictionary and Increment Count if DictA key,values Exists in DictB?

I have Two Dictionary DictA & DictB such as:
Dictionary<int, string> DictA = new Dictionary<int, string>();
DicA.add(1,"Mango");
DicA.add(2,"Grapes");
DicA.add(3,"Orange");
Dictionary<int, string> DictB = new Dictionary<int, string>();
DicB.add(1,"Mango");
DicB.add(2,"Pineapple");
How to Compare the values of these Two Dictionary DictA key,value with DictB key,value and if MATCH IS FOUND then INCREMENT the COUNTER variable.
Note: DicA may Contains many Rows as compared to DicB
EG: DicA has 3 Rows and DicB has 2 Rows. If DicA key,value match(similar/equal) to DicB key,val then increment the counter variable by one!
Any Suggestion..! Help Appreciated...!
Use this code:
int matches = DictA.Keys.Where(k => DictB.ContainsKey(k) && DictB[k] == DictA[k]).Count();
You could use:
Dictionary<int, string> DicA = new Dictionary<int, string>();
DicA.Add(1,"Mango");
DicA.Add(2,"Grapes");
DicA.Add(3,"Orange");
Dictionary<int, string> DicB = new Dictionary<int, string>();
DicB.Add(1,"Mango");
DicB.Add(2,"Pineapple");
int counter = 0;
foreach (var pair in DicA)
{
string value;
if (DicB.TryGetValue(pair.Key, out value))
{
if (value == pair.Value)
{
counter++;
}
}
}

Categories