Hashtable - storing hashtable objects inside a hashtable

Bonekrusher

Active member
Joined
Jul 4, 2007
Messages
38
Programming Experience
1-3
Hi,

I am trying to write some code which will allow me to store some values in a hashtable, then store that hashtable object in another hashtable.

I am able to create the hashtables, but I am having trouble retrieving the data.

VB.NET:
Public Class MyHash
    Public table As New Hashtable()
    Public Sub addHash(ByVal tablename As String, ByVal key As Object, ByVal value As String)

        If table.ContainsKey(tablename) Then
            Dim hashTable As New Hashtable()
            hashTable.Add(key, value)

        Else
            Dim hashTable1 As New Hashtable()
            hashTable1.Add(key, value)
            table.Add(tablename, hashTable1)
        End If

    End Sub

    Public Function getHash(ByVal tablename As String, ByVal key As Object)

        Dim value As String = ""
        If table.ContainsKey(tablename) Then
            Dim viewHash As New Hashtable()

            viewHash = table.Clone(tablename)

            If viewHash.ContainsKey(key) Then
                value = viewHash.Item(key).ToString()
            Else
                value = "null"
            End If

        End If
        For Each data As DictionaryEntry In table
            MsgBox(data.Key & "  " & data.Value.ToString)
        Next
        Return value
    End Function
End Class

My hashtable "table" holds the collection of hashtables. In function "getHash" I need to retrieve the hashtable from "tables" and then copy the hashtable to "viewHash". Once that has happened I can then retrieve some values by key. The problem (I think) is that I am not copying the hashtable correctly:
VB.NET:
viewHash = table.Clone(tablename)

I hope I explained my problem correctly.

Thanks for the help.
 
If your table contains the key you retrieve the value object and cast it from Object to HashTable like this:
VB.NET:
Dim value As Hashtable = CType(table(tablename), Hashtable)
If you're using .Net 2.0 and above you should use the Dictionary(Of Tkey, Tvalue) instead of HashTable.
 
Thanks,

That did the trick. BTW why:

If you're using .Net 2.0 and above you should use the Dictionary(Of Tkey, Tvalue) instead of HashTable.

Is it more more efficient than a hashtable because I need to declare the types of keys and value pairs when an instance of the Dictionary class is created?

Thanks
 
It is as efficient, but it is strongly typed, which is good, and saves you casting.
 
Here is the revised code. Thanks again!

VB.NET:
 Public Sub addDic(ByVal tablename As String, ByVal key As String, ByVal value As String)

        If table.ContainsKey(tablename) Then
            Dim dicTable As New Dictionary(Of String, String)
            dicTable.Add(key, value)
        Else

            Dim dicTable1 As New Dictionary(Of String, Object)
            dicTable1.Add(key, value)
            dTable.Add(tablename, dicTable1)
        End If


    End Sub

    Public Function getDic(ByVal tablename As String, ByVal key As String) As String

        Dim value As String = ""
        If dTable.ContainsKey(tablename) Then
            Dim viewHash As New Dictionary(Of String, Object)
            viewHash = dTable(tablename)

            If viewHash.ContainsKey(key) Then
                value = viewHash.Item(key).ToString()
            Else
                value = "null"
            End If

        End If

        Return value
    End Function
:)
 
Aren't your AddDic method supposed to add the key and value for existing table?
VB.NET:
xTable(tablename).Add(key, value)
 
Nice catch!

Here is the revised code:

VB.NET:
Public dTable As New Dictionary(Of String, Object)
    Public Sub addDic(ByVal tablename As String, ByVal key As String, ByVal value As String)

        If dTable.ContainsKey(tablename) Then

            dTable(tablename).Add(key, value)

        Else

            Dim dicTable1 As New Dictionary(Of String, Object)
            dicTable1.Add(key, value)
            dTable.Add(tablename, dicTable1)

        End If
    End Sub

    Public Function getDic(ByVal tablename As String, ByVal key As String) As String

        Dim value As String = ""
        If dTable.ContainsKey(tablename) Then
            Dim viewHash As New Dictionary(Of String, Object)
            viewHash = dTable(tablename)

            If viewHash.ContainsKey(key) Then
                value = viewHash.Item(key).ToString()
            Else
                value = "null"
            End If

        End If

        Return value
    End Function
 
Use the New keyword only when you want to create a new object. In your GetDic method you create a new dictionary and assign it to the viewHash variable, then you assign viewHash variable a dictionary by tablename. Why did you create that first dictionary? This is what you would want to do:
VB.NET:
Dim viewHash As Dictionary(Of String, Object) = dTable(tablename)
And since your value is type String that dictionary should have value type as String as well, ie Dictionary(Of String, String).
 
Hi John,

Originally I thought I needed to create a new instance in order to pass dTable(tablename) to viewHash.

VB.NET:
 Dim viewHash As New Dictionary(Of String, Object)
 viewHash = dTable(tablename)

How come I do not have to create a new instance of "viewHash" and I need to for dTable. Is this because viewHash is a reference to dTable?

Thanks for the help!
 
Declaring a variable, creating an instance, and assigning a value/reference to a variable is three different things.

  1. Declaring a variable and type:
    VB.NET:
    Dim variable As Button
  2. creating an instance:
    VB.NET:
    New Button
  3. assignment of value/reference to a variable
    VB.NET:
    variable = aButtonref
Dim x As New Button is the short form for:
VB.NET:
Dim x As Button = New Button
 
Hi John,

Originally I thought I needed to create a new instance in order to pass dTable(tablename) to viewHash.

VB.NET:
 Dim viewHash As New Dictionary(Of String, Object)
 viewHash = dTable(tablename)

How come I do not have to create a new instance of "viewHash" and I need to for dTable. Is this because viewHash is a reference to dTable?

Thanks for the help!
That code is saying this:

1. Declare a variable named viewHash of type Dictionary(Of String, Object).
2. Create a new Dictionary(Of String, Object) object and assign it to the viewHash variable.
3. Get an existing Dictionary(Of String, Object) from dTable and assign it to the viewHash variable.

Now, what did you create a new object for if you are just going to discard it and use an existing object? Let me provide you with an analogy. Let's say that you live in a house with no garage, so you park your car on the street. You want to get your car off the street so you go out and get a DIY car port and attach it to the side of your house. You also buy a new car and put it under the car port. You then take the new car out of the car port and throw it away so you can put your existing car under the car port.

Does that sound sensible? Why would you buy a new car and put it under the car port when you're just going to immediately throw it away and put your existing car under the car port? Your code is exactly the same. Why create a new Dictionary and assign it to the variable if you're just going to immediately throw it away and assign an existing Dictionary to that variable.

Something that may make it clearer what you're doing is the fact that this:
VB.NET:
Dim viewHash As New Dictionary(Of String, Object)
is just a shorthand for this:
VB.NET:
Dim viewHash As Dictionary(Of String, Object) = New Dictionary(Of String, Object)
 
Ah, bummer! I must have looked at the first page and didn't see JohnH's last reply. Oh well. Hopefully two posts makes it doubly clear.

Well.. I liked the analogy ;)

And it reminded me, my poor car is sitting out in the freezing cold because I couldn't get it back in the garage due to the doorway being blocked by another car. sniffle
 
Here is some simpler code:

VB.NET:
    'public entities DO NOT have lowercase first letters
    Private dTable As New Dictionary(Of String, Dictionary(Of String, String))

    'methods DO NOT have lowercase first letters
    Public Sub AddDic(ByVal tablename As String, ByVal key As String, ByVal value As String)

      'if the tablename isnt there, make a new instance
      If Not dTable.ContainsKey(tablename) Then dTable(tablename) = New Dictionary(Of String, String)

      'store the value
      dTable(tablename)(key) = value

    End Sub

    Public Function GetDic(ByVal tablename As String, ByVal key As String) As String

      Try
        'if any part of this goes bang, "null" will be returned
        Return dTable(tablename)(key)
      Catch Exception
        Return "null"
      End Try

    End Function
[/QUOTE]

This might be easier to visualize!
 
Back
Top