【问题标题】:New dictionary based on existing dictionary yields unexpected results基于现有字典的新字典产生意想不到的结果
【发布时间】:2021-06-29 23:08:10
【问题描述】:

我希望从现有字典对象中获取一些数据,并创建一个新字典对象,并根据键值重新组织该数据。

在我们的假设示例中,我有 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)
阿尔法 -- (User1, User2, User3)
测试版——(用户 4、用户 5、用户 6、用户 7)

但是,我得到的结果是:
用户 -- (User1, ..., User7) -- 正确
Alpha -- (User1, ..., User7) -- 不正确
Beta -- (User4, User5, User6, User7) -- 正确

有趣的是,在检查本地变量时(在 VS Debug 中),“origDictionary”也以某种方式被修改了。在生成“newDictionary”后回顾“origDictionary”,显示的值与最初填充的值不同。

我错过了什么?是 ByVal 还是 ByRef 的问题?

(这个问题已经泛化了。没有使用真实数据或专有代码)

【问题讨论】:

  • 我没有测试过,但我怀疑将dict.Add(key, val) 更改为dict.Add(key, val.ToList()) 将解决您的问题。
  • 请记住List 是一个引用类型,所以如果你不小心,你会将同一个列表的引用放在两个不同的字典项中。调用ToList 将创建一个新列表,其内容与之前的列表相同,您也可以使用New List(Of String)(val) 之类的名称,它更明确地说明您要执行的操作。

标签: vb.net dictionary


【解决方案1】:

我刚刚测试了我的理论,我是对的。改变这个:

dict.Add(key, val)

到这里:

dict.Add(key, val.ToList())

如果您在调试器中逐步执行Main 方法并使用您的代码和我的代码观察origDictionary("2018").CountorigDictionary("2019").Count 的值,您应该能够了解问题所在。您拥有的代码是将现有Dictionary 中的相同List 对象添加到Else 块中的新对象,因此您对AddRange 的调用将影响那些现有Lists。我的代码创建了一个新的List 并将其添加到新的Dictionary,因此对AddRange 的调用只会影响新的List,而不是现有的。

【讨论】:

    猜你喜欢
    • 2014-05-04
    • 1970-01-01
    • 1970-01-01
    • 2019-11-17
    • 2022-01-17
    • 2021-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多