Reputation: 13
I'm looking to take some data from an existing dictionary object and create a new dictionary object with that data reorganized based on key values.
In our hypothetical example, I've got 7 Users (User1... User7). Their year of employment populates the key of the original dictionary and the usernames associated with that key are stored in the value as a list of strings (i.e. User1 was hired in 2018, User4 in 2019, etc.)
I then want to walk through that original dictionary and populate a new dictionary. Everyone is considered a "User" and should be added to the value associated with the "Users" key. Then, hires from 2018 should be added to the list associated with the "Alpha" key. Everything else should go to the list associated with the "Beta" key.
Sub Main(args As String())
'create dictionary
Dim origDictionary As New Dictionary(Of String, List(Of String))
'create entries in the original dictionary
origDictionary.Add("2018", New List(Of String) From {"User1", "User2", "User3"})
origDictionary.Add("2019", New List(Of String) From {"User4", "User5"})
origDictionary.Add("2020", New List(Of String) From {"User6", "User7"})
'convert that dictionary based on our qualifiers
Dim newDictionary As New Dictionary(Of String, List(Of String))
For Each pair As KeyValuePair(Of String, List(Of String)) In origDictionary
'every user goes into the user group
appendToDict("Users", pair.Value, newDictionary)
'users are also sorted into more specific groups
Select Case pair.Key
Case "2018"
appendToDict("Alpha", pair.Value, newDictionary)
Case Else
appendToDict("Beta", pair.Value, newDictionary)
End Select
Next
End Sub
Private Sub appendToDict(key As String, val As List(Of String), dict As Dictionary(Of String, List(Of String)))
If dict.ContainsKey(key) Then
dict(key).AddRange(val)
Else
dict.Add(key, val)
End If
End Sub
The expected result should be:
Users -- (User1, ..., User7)
Alpha -- (User1, User2, User3)
Beta -- (User4, User5, User6, User7)
However, the result I'm getting is:
Users -- (User1, ..., User7) -- Correct
Alpha -- (User1, ..., User7) -- Not correct
Beta -- (User4, User5, User6, User7) -- Correct
Interestingly, when inspecting the local vars (in VS Debug), the "origDictionary" is also somehow being modified. Looking back at "origDictionary" AFTER "newDictionary" has been generated shows different values than what was originally populated.
What am I missing? Is it a ByVal vs. ByRef thing?
(This problem has been generalized. No real data or proprietary code has been used)
Upvotes: 1
Views: 72
Reputation: 54417
I just tested my theory and I was right. Change this:
dict.Add(key, val)
to this:
dict.Add(key, val.ToList())
If you step through your Main
method in the debugger and watch the values of origDictionary("2018").Count
and origDictionary("2019").Count
using your code and mine, you should be able to get an idea of what the issue is. The code you have is adding the same List
objects from the existing Dictionary
to the new one in the Else
block, so your call to AddRange
will affect those existing Lists
. My code creates a new List
and adds that to the new Dictionary
, so the call to AddRange
will only affect that new List
, not the existing one.
Upvotes: 1