Compile error while adding items to nested dictionary - vb.net

I am trying to created nested dictionary variable like the below, But I get compile error stating that it needs "}" at line where I am adding items (line #2) to my nested dictionary.
What Am I missing here? Thanks.
Dim myNestedDictionary As Dictionary(Of String, Dictionary(Of String, Integer)) = New Dictionary(Of String, Dictionary(Of String, Integer))()
myNestedDictionary.Add("A", New Dictionary("A", 4)())

In VS 2008 and .net 3.5 you cannot declare and initialize a Dictionary in one line, so you have to do:
Dim myNestedDictionary As New Dictionary(Of String, Dictionary(Of String, Integer))()
Dim lTempDict As New Dictionary(Of String, Integer)
lTempDict.Add("A", 4)
myNestedDictionary.Add("A", lTempDict)
To retrieve the an item use the following:
Dim lDictionaryForA As Dictionary(Of String, Integer) = myNestedDictionary.Item("A")
Dim lValueForA As Integer = lDictionaryForA.Item("A")
The value in lValueForA should be 4.

You need to specify the type of dictionary you are creating when you add the records:
myNestedDictionary.Add("A", New Dictionary(Of String, Integer))
or otherwise pass an existing Dictionary(Of String, Integer) as the inside-dictionary argument (when adding key/value pairs to the external dictionary).
(BTW, Your external dictionary is a dictionary who's Keys are Strings and Values are Dictionaries (Of String, Integer), is this really what you wanted?)

In C# you can do that:
var myNestedDictionary = new Dictionary<string, Dictionary<string, int>>() {{ "A", new Dictionary<string, int>() { { "A", 4 } } }};
You can do it in VB 2010 as well, using the From keyword, but it doesn't compile in VS 2008. It will compile in VB 2010, no matter which .NET Framework you target. I've tried 2.0, 3.5 and 4.0.
Dim myNestedDictionary = New Dictionary(Of String, Dictionary(Of String, Integer))() From {{"A", New Dictionary(Of String, Integer) From {{"A", 4}}}}

Related

Convert a List to a Dictionary with a unique numbered key

How can this code be accomplished using ToDictionary() instead of a For Each
Dim stringDict As Dictionary(Of String, String) = new Dictionary(Of Integer, String)
Dim stringList As List(Of String) = {"alpha", "beta", "gamma", "delta"}
For Each stringItem As String In stringList
stringDict.Add($"Entry{stringDict.Count+1}",stringItem)
Next
This is what I am trying to do:
Dim stringDict As Dictionary(Of String, String) = stringList.ToDictionary(Function(a) $"Entry{?}", Function(b) b)
I was hoping there might be a variable with the current row or index, or an incrementor
You can use the overload of Select that gives you the index:
Dim stringDict As Dictionary(Of String, String) = stringList.
Select(Function(s, index) (Key:=$"Entry{index + 1}", Value:=s)).
ToDictionary(Function(kv) kv.Key, Function(kv) kv.Value)
However, i find your loop more readable. You should also set Option Strict to On, following should give you a compiler error:
Dim stringDict As Dictionary(Of String, String) = new Dictionary(Of Integer, String)
You can use Enumerable.Range (documentation) to create a range of numbers from 1 to the Count of your List and then Enumerable.ToDictionary (documentation) to convert that range to a Dictionary.
Example:
Dim stringList As New List(Of String) From {"alpha", "beta", "gamma", "delta"}
Dim stringDict = Enumerable.Range(1, stringList.Count).ToDictionary(Function(i) $"Entry{i}", Function(i) stringList.Item(i - 1))
Fiddle: https://dotnetfiddle.net/4xHp9g

Convert Dictionary(Of String, Object) to Dictionary(Of String, String)

When I try to pass a Dictionary(Of String, Object) to a function parameter that wants a Dictionary(Of String, String) I get the following error:
Unable to cast object of type 'System.Collections.Generic.Dictionary'2[System.String,System.Object]' to type 'System.Collections.Generic.Dictionary'2[System.String,System.String]'.
All of the Object values in the dictionary are strings but the dictionary was declared as String/Object. I would have thought that the system would be able to convert this but since it isn't I need to do it myself.
I looked at the .ToDictionary() prototype method but all of the examples show a list being converted to a dictionary.
I found this question which has an accepted answer for what I want but it's written in C# and I can't figure out the conversion to VB.Net.
Edit 1
Offending code. Obviously boiled down or else I would just simply declare dict1 as string/string in my actual code.
Dim dict1 As New Dictionary(Of String, Object) From {{"key1","value1"}}
SomeFunctionThatExpectsParamToBeDictOfStringString(dict1)
Edit 2
I tried:
SomeFunctionThatExpectsParamToBeDictOfStringString(dict1.ToDictionary(Function(k) k.Key, Function(v) v.Value.ToString()))
but got:
System.MissingMemberException: Public member 'ToDictionary' on type 'Dictionary(Of String,Object)' not found.
This could be the VB.NET version of the C# code you have linked
Dim dic1 As Dictionary(Of String, Object) = New Dictionary(Of String, Object)
dic1.Add("A", "B")
Dim dic2 As Dictionary(Of String, String) = dic1.ToDictionary(Function(k) k.Key,
Function(v) v.Value.ToString())

associative array like in php in vb.net

in PHP we know to make associative array using this code
$variable = array('0001'=>'value1', '0010'=>'value2');
and to print all keys and values using this code
foreach($variable as $key1 => $val1)
foreach($val1 as $key2 => $val2)
echo ("$key2 => $val2 <br />")
and the question is how to perform this in vb.net?
as i know to make associative array in vb.net using this :
Dim var As New Collection
var.Add("value1", "0001")
var.Add("value2", "0010")
how about to print value and key in vb.net like foreach in PHP? thanks
Although i'm not familiar with PHP (anymore), i assume that associative arrays are the equivalent of a HashTable or the more modern, strongly typed Dictionary:
Dim dict = New Dictionary(Of String, String)
dict.Add("value1", "0001")
dict.Add("value2", "0010")
Normally you would lookup keys:
Dim val2 = dict("value2") ' <-- 0010
But if you want to enumerate it (less efficient):
For Each kv As KeyValuePair(Of String, String) In dict
Console.WriteLine("Key:{0} Value:{1}",kv.Key, kv.Value)
Next
Dim row As Dictionary(Of String, Object)
Dim rows As Dictionary(Of String, Object)
row = New Dictionary(Of String, Object)
rows = New Dictionary(Of String, Object)
row.Add("a", 11)
row.Add("b", 22)
rows.Add("ab", row)

List of Dictionary Arrays

Hit a wall, and can't find much in docs.
I have two dictionaries, and I'd like to put them in a list.
Dim listOfDictionaries As List(Of Dictionary(Of String, String))
is not working.
Am I correct in assuming that once I get this dimmed, I can .add the conventional way?
Details (EDIT)
When trying to listOfDictionaries.Add(dictionaryIWantToAdd), I get "value of type '1-dimensional array system.collection.generic.dictionary(of string, string)' cannot be converted to 'system.collection.generic.dictionary(of string, string)'
Solution
Helps to put the () on the end an array. :P
The conventional way is:
Dim both = New List(Of Dictionary(Of String, String))()
both.Add(Dictionary1)
both.Add(Dictionary2)
The error says it all. You are trying to add an array of dictionaries to the list, but the add method only takes a single dictionary, not an array of them. Either fix it so you are only passing in a single dictionary:
Dim myDictionary As Dictionary(Of String, String)
' ...
listOfDictionaries.Add(myDictionary)
Or use the AddRange method to add all the dictionaries in the array at once:
Dim myArrayOfDictionaries() As Dictionary(Of String, String)
' ...
listOfDictionaries.AddRange(myArrayOfDictionaries)
I tend to favour single-line solutions when it's something straightforward like this, making use of the From keyword.
Dim listOfDictionaries = New List(Of Dictionary(Of String, String)) From { dictionary1, dictionary2 }

How do I write this lambda select method in VB.net?

For I've tried this:
Dim exampleItems As Dictionary(Of String, String) = New Dictionary(Of String, String)
Dim blah = exampleItems.Select (Function(x) New (x.Key, x.Value)).ToList 'error here
But I'm getting a syntax error and all the examples that I've seen are in C#.
This would be:
Dim blah = exampleItems.Select (Function(x) New With { .Key = x.Key, .Value = x.Value }).ToList
For details, see Anonymous Types. (Depending on usage, you might also want Key or Value to be flagged with the Key keyword.)
That being said, Dictionary(Of TKey, Of TValue) already is an IEnumerable(Of KeyValuePair(Of TKey, Of TValue), so you can also just do:
Dim blah = exampleItems.ToList
And you'll have a list of KeyValuePair, which has a Key and Value property already. This really means there's no need to make the anonymous type.