Linq on nested Dictionary - c#

I have a dictionary of dictionary and I want to find a value from inner dictionary by Linq .
My code is:
private Dictionary<string, Dictionary<int, string>> SubCategoryDictionary = new Dictionary<string, Dictionary<int, string>>();
private Dictionary<int, string> BGA_Dictionary = new Dictionary<int, string>();
private Dictionary<int, string> Lead3D_Dictionary = new Dictionary<int, string>();
private Dictionary<int, string> Lead2D_Dictionary = new Dictionary<int, string>();
private Dictionary<int, string> Leadless_Dictionary = new Dictionary<int, string>();
private Dictionary<int, string> PIC_Dictionary = new Dictionary<int, string>();
In my constructor I have all values like this:--
BGA_Dictionary.Add(1, "Body_Measurement");
BGA_Dictionary.Add(2, "Ball_Measurement");
SubCategoryDictionary.Add("BGA", BGA_Dictionary);
Lead3D_Dictionary.Add(1, "Component_Height");
Lead3D_Dictionary.Add(2, "Rib_Measurement");
SubCategoryDictionary.Add("Package", Lead3D_Dictionary);
Lead2D_Dictionary.Add(1, "Dirt_Inspection");
Lead2D_Dictionary.Add(2, "Half_Cut_Inspection");
SubCategoryDictionary.Add("Mark", Lead2D_Dictionary);
Now I need a Lambda expression which will give me something like :
when key of SubCategoryDictionary ="Mark" and key of Lead3D_Dictionary =2 then I should get "Rib_Measurement".
I tried with following code :
string q = (from cls in SubCategoryDictionary
from s in cls.Value
where cls.Key == "Mark" && s.Key == 3
select s.Value).FirstOrDefault();
foreach (var a in q)
{
}
This above code works but I need in lambda expression. So if someone help me in formation of Lambda formation. It will be of great help.
Thanks.

I'm not sure why you ever need a lambda for accessing a dictionary by keys, but here it is:
Func<string,int,string> lambda = (k1, k2) => SubCategoryDictionary[k1][k2];
Now you can invoke it with var subCategory = lambda("Mark", 2);

I guess below code should get you the value you are trying to get.
var lead3 = SubCategoryDictionary["Mark"].SingleOrDefault(x => x.Key == 2).Value;
The idea is to use the Key of the first dictionary and get the value of it than filter it with SingleOrDefault method by providing a key to the inner dictionary value you are interested in.
Hope this helps

Related

Is it possible to store a KeyValuePair of a dictionary without the use of a foreach loop?

The syntax for iterating over a dictionary with a foreach loop is:
foreach (KeyValuePair<key, value> item in dictionary)
Inside the foreach loop the key is accessed with item.key and the value with item.value.
This got me thinking, can this be used without the use of a foreach loop as a convenient (although niche) way to represent a specific dictionary pair?
I am not looking for some weird work arounds, like running a foreach loop and saving the KeyValuePair into a variable once the target key is reached, because at this point it would be more convenient to just use 2 variables.
Like this
var dic = new Dictionary<string, int>();
dic["a"] = 42;
KeyValuePair<string, int> keyVal;
foreach(var kv in dic) {
keyVal = kv; << gets the last entry from the dictioanry
}
Note that the dictionary does not store KeyValuePairs, it creates one for the enumeration, so the simple thing to do is this (because we are not expensively recreating something)
var dic = new Dictionary<string, int>();
dic["a"] = 42;
KeyValuePair<string, int> keyVal = new KeyValuePair<string, int>("a", dic["a"]);
this is more efficient than the (neat) LINQ Sinlge method
The IDictionary<TKey, TValue> interface implements IEnumerable<KeyValuePair<TKey,TValue>>. This means you can simply use Single() to get the entry you want.
IDictionary<string, int> dict = ...;
KeyValuePair<string, int> entry = dict.Single(it => it.Key == "yourKey");
try this
var dict = new Dictionary<string, string>() {
{"hi","Hello World!"},
{"adieu","Goodby"}
};
string hi = dict["hi"]; //Hello World!
or if you want a list
List<KeyValuePair<string,string>> list = dict.ToList();
result
[{"Key":"hi","Value":"Hello World!"},{"Key":"adieu","Value":"Goodby"}]

C# - Retrieve data from Database and store in 2 dimension dictionary?

Hello I try to do something like PHP thing that is retrieve data from database and store in 2 dimension collection (Dictionary)
I'm not sure I write it correctly or not.
Let's say my database table and expected structure result look like this (See the screenshot)
Click to see screenshot
public ActionResult ShowBook()
{
var books = from v in db.Books
select v;
Dictionary<string, Dictionary<string, string>> test = new Dictionary<string, Dictionary<string, string>>();
foreach (var item in books)
{
test[item.Book_Type_ID][item.Author_ID] = item.Book_Name;
}
return .....
}
But I has this error
System.Collections.Generic.KeyNotFoundException: 'The given key was not present in the dictionary.'
How could I do?
The problem is you have to initialize each inner Dictionary<string, string> when assigning a new key to your outer dictionary. Typically this means checking if this key exists, and if not, creating the object:
foreach (var item in books)
{
if(!test.ContainsKey(item.Book_Type_ID))
{
test[item.Book_Type_ID] = new Dictionary<string, string>();
}
//now we are sure it exists, add it
test[item.Book_Type_ID][item.Author_ID] = item.Book_Name;
}
The dictionary is 2-dimensional. When you initialize it
Dictionary<string, Dictionary<string, string>> test = new Dictionary<string, Dictionary<string, string>>();
The first dimension is initialized, but not the second - i.e. test is an empty dictionary. So when you try to add a book title to a second-dimension dictionary, there isn't a dictionary for it to be added to yet. You need to check this condition first, and create an entry if it doesn't already exist:
var books = from v in db.Books select v;
Dictionary<string, Dictionary<string, string>> test = new Dictionary<string, Dictionary<string, string>>();
foreach (var item in books)
{
if (!test.ContainsKey(item.Book_Type_ID))
test[item.Book_Type_ID] = new Dictionary<string, string>();
test[item.Book_Type_ID][item.Author_ID] = item.Book_Name;
}

Adding a key value pair in a dictionary inside a dictionary

I have a dictionary < string,object > which has a mapping of a string and a dictionary < string,int >. How do I add a key value pair in the inside dictionary < string ,int > ?
Dictionary <string,object> dict = new Dictionary <string,object>();
Dictionary <string,int> insideDict = new Dictionary <string,int>();
// ad some values in insideDict
dict.Add("blah",insideDict);
So now the dict has a dictionary mapped with a string.Now I want to separately add values to the insideDict.
I tried
dict["blah"].Add();
Where am I going wrong?
Do you mean something like this?
var collection = new Dictionary<string, Dictionary<string, int>>();
collection.Add("some key", new Dictionary<string, int>());
collection["some key"].Add("inner key", 0);
Something like below
Dictionary<string, object> dict = new Dictionary<string, object>();
dict.Add("1", new Dictionary<string, int>());
(OR) if you already have defined the inner dictionary then
Dictionary<string, object> dict = new Dictionary<string, object>();
Dictionary<string, int> innerdict = new Dictionary<string, int>();
dict.Add("1", innerdict); // added to outer dictionary
string key = "1";
((Dictionary<string, int>)dict[key]).Add("100", 100); // added to inner dictionary
Per your comment tried this but screwed up somewhere
You didn't got it cause of your below line where you forgot to cast the inner dictionary value to Dictionary<string, int> since your outer dictionary value is object. You should rather have your outer dictionary declared strongly typed.
dict.Add("blah",insideDict); //forgot casting here
Dictionary<string, Dictionary<string,TValue>> dic = new Dictionary<string, Dictionary<string,TValue>>();
Replace the TValue with your value type.

How can I get the inner list value of list of keyvaluepair of (string, list)?

I am now struggling to find a way to get inner list from complicated List of keyvalupair.
public static List<KeyValuePair<string, List<KeyValuePair<int, string>>>> conditions = new List<KeyValuePair<string, List<KeyValuePair<int, string>>>>();
I want list from above list using given string value as a key.
Can anyone help me please?
You can use FirstOrDefault method like this:
conditions.FirstOrDefault(x => x.Key == "key").Value;
Or you should probably use a Dictionary instead.
You could use a Dictionary and a Dictionary as your value as well.
public static Dictionary<string, Dictionary<int, string>> conditions = new Dictionary<string, Dictionary<int, string>>();
and access it with conditions[key]
For example:
//Initialize random, pointless dictionary for example
var conditions = new Dictionary<string, Dictionary<int, string>>
{
{
"firstDict", new Dictionary<int, string>
{
{1, "blue"},
{2, "red"}
}
},
{
"secondDict", new Dictionary<int, string>
{
{1, "car"},
{2, "truck"}
}
}
};
//Get dictionary with key value "firstDict"
var firstDict = conditions["firstDict"];
//Gets the value associated with key "1"
var color = firstDict[1];

How to use nested dictionary in C#?

My requirement is
Dictionary<outerString, Dictionary<innerString, List<SelectListItem>>>
When I try to get the value of the inner Dictionary using key(outerString), it gives an error saying "cannot apply indexing with type of expression...............".
I have tried this
Dictionary<outerString, Dictionary<innerString, List<SelectListItem>>> dict1 = new
Dictionary<outerString, Dictionary<innerString, List<SelectListItem>>>;
Dictionary<innerString, List<SelectListItem>> dict2 = dict1.values["outerString"];
Any quick help will be greatly appreciated.
Thx in advance.
I guess what you need is just:
Dictionary<innerString, List<SelectListItem>> dict = dict1["someKey"];
You just need to change the last line of your code snippet to (I assumed where you wrote inner string and outer string you must meant string):
var dict = dict1["someValue"];
Additionally, you could probably make your code much readable with the var keyword:
var dict1 = new Dictionary<string, Dictionary<string, List<SelectListItem>>>();
var dict = dict1["someValue"];
So outerString and innerString are types? Did you actually just want a nested dictionary string -> string -> List<SelectListItem> ? If not, you'll have to show us the definition of these types, and give the compiler some way to convert from the string you are trying to index with...
You were close:
Dictionary<outerString, Dictionary<innerString, List<SelectListItem>>> dict1 = new
Dictionary<outerString, Dictionary<innerString, List<SelectListItem>>>();
// Get inner dictionary whose key is "someValue"
Dictionary<innerString, List<SelectListItem>> dict = dict1["someValue"]
Did I misunderstand you? This works fine
Dictionary<string, Dictionary<string, List<string>>> list = new Dictionary<string, Dictionary<string, List<string>>>();
list.Add("test", new Dictionary<string, List<string>>());
Dictionary<string, List<string>> inner = list["test"];
or
var list = new Dictionary<string, Dictionary<string, List<string>>>();
list.Add("test", new Dictionary<string, List<string>>());
Dictionary<string, List<string>> inner = list["test"];
In
Dictionary<string, Dictionary<string, List<T>> dict1 =
new Dictionary<string, Dictionary<string, List<T>>();
you need
List<T> list12 = dict1["key1"]["key2"];
List<int> list1 = new List<int>();
list1.Add(1);
list1.Add(2);
Dictionary<string, List<int>> innerDict = new Dictionary<string, List<int>>();
innerDict.Add("inner", list1);
Dictionary<string, Dictionary<string, List<int>>> dict1 =
new Dictionary<string, Dictionary<string, List<int>>>();
dict1.Add("outer", innerDict);
List<int> list2 = dict1["outer"]["inner"];
How about you use an array of strings for a key, rather than trying to nest the dictionaries -
Dictionary<string[], List<string>> dict =
new Dictionary<string[],List<string>>();
string[] key = {"inner", "outer"};
List<string> vals = new List<string>();
dict.Add(key, vals);

Categories

Resources