基于现有词典的新词典产生意外结果
New dictionary based on existing dictionary yields unexpected results
我想从现有的字典对象中获取一些数据,并创建一个新的字典对象,其中包含基于键值重新组织的数据。
在我们的假设示例中,我有 7 个用户(User1...User7)。他们的工作年份填充了原始字典的键,与该键关联的用户名作为字符串列表存储在值中(即 User1 于 2018 年受雇,User4 于 2019 年等)
然后我想遍历那个原始词典并填充一个新词典。每个人都被视为“用户”,应该添加到与“用户”键关联的值中。然后,应将 2018 年的雇员添加到与“Alpha”键关联的列表中。其他所有内容都应转到与“Beta”键关联的列表。
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
预期结果应该是:
用户 -- (User1, ..., User7)
Alpha --(用户 1、用户 2、用户 3)
测试版 -- (User4, User5, User6, User7)
然而,我得到的结果是:
用户 -- (User1, ..., User7) -- 正确
Alpha -- (User1, ..., User7) -- 不正确
Beta -- (User4, User5, User6, User7) -- 正确
有趣的是,在检查本地变量时(在 VS 调试中),“origDictionary”也以某种方式被修改。在生成“newDictionary”之后回顾“origDictionary”显示的值与最初填充的值不同。
我错过了什么?是 ByVal 还是 ByRef 的问题?
(这个问题已经被普遍化了。没有使用真实数据或专有代码)
我刚刚测试了我的理论,我是对的。改变这个:
dict.Add(key, val)
对此:
dict.Add(key, val.ToList())
如果您在调试器中单步执行 Main
方法并使用您和我的代码观察 origDictionary("2018").Count
和 origDictionary("2019").Count
的值,您应该能够了解问题是什么。您拥有的代码是将现有 Dictionary
中的相同 List
对象添加到 Else
块中的新对象,因此您对 AddRange
的调用将影响那些现有 Lists
。我的代码创建了一个新的 List
并将其添加到新的 Dictionary
,因此对 AddRange
的调用只会影响新的 List
,而不影响现有的 [=24] =]
我想从现有的字典对象中获取一些数据,并创建一个新的字典对象,其中包含基于键值重新组织的数据。
在我们的假设示例中,我有 7 个用户(User1...User7)。他们的工作年份填充了原始字典的键,与该键关联的用户名作为字符串列表存储在值中(即 User1 于 2018 年受雇,User4 于 2019 年等)
然后我想遍历那个原始词典并填充一个新词典。每个人都被视为“用户”,应该添加到与“用户”键关联的值中。然后,应将 2018 年的雇员添加到与“Alpha”键关联的列表中。其他所有内容都应转到与“Beta”键关联的列表。
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
预期结果应该是:
用户 -- (User1, ..., User7)
Alpha --(用户 1、用户 2、用户 3)
测试版 -- (User4, User5, User6, User7)
然而,我得到的结果是:
用户 -- (User1, ..., User7) -- 正确
Alpha -- (User1, ..., User7) -- 不正确
Beta -- (User4, User5, User6, User7) -- 正确
有趣的是,在检查本地变量时(在 VS 调试中),“origDictionary”也以某种方式被修改。在生成“newDictionary”之后回顾“origDictionary”显示的值与最初填充的值不同。
我错过了什么?是 ByVal 还是 ByRef 的问题?
(这个问题已经被普遍化了。没有使用真实数据或专有代码)
我刚刚测试了我的理论,我是对的。改变这个:
dict.Add(key, val)
对此:
dict.Add(key, val.ToList())
如果您在调试器中单步执行 Main
方法并使用您和我的代码观察 origDictionary("2018").Count
和 origDictionary("2019").Count
的值,您应该能够了解问题是什么。您拥有的代码是将现有 Dictionary
中的相同 List
对象添加到 Else
块中的新对象,因此您对 AddRange
的调用将影响那些现有 Lists
。我的代码创建了一个新的 List
并将其添加到新的 Dictionary
,因此对 AddRange
的调用只会影响新的 List
,而不影响现有的 [=24] =]