【问题标题】:Dictionary entries with two keys - VB.net带有两个键的字典条目 - VB.net
【发布时间】:2013-09-19 18:07:11
【问题描述】:

.net 专家会推荐什么? 我有一段数据需要使用两个不同的键来访问。假设数据如下所示:

key1
key2
data

我需要通过任一键添加、查找数据并使用任一键删除数据数千次,并且希望非常快速。

我真的很喜欢 LINQ 为代码添加的清晰度,但是……我已经将 LINQ 与循环检索情况下的字典进行了比较。我不喜欢 LINQ,因为它看起来需要更多时间来获取任何单个数据。我喜欢字典,因为它们的检索速度非常快。

我正在考虑编写一个使用两个字典的自定义类:

key1
data

key2
data

每当我向类的实例添加数据项时,该类都需要将数据添加到两个不同的支持字典中。每次我删除一个数据项时,我都需要从两个支持字典中删除它们。

这是处理此问题的最佳方法,还是 .net 中有一些快速的“类似字典”的数据结构允许我为相同的数据拥有两个键?

【问题讨论】:

  • @KevinDiTraglia 看起来他想使用key1 搜索项目 key2,当您链接的问题需要两者时key1 key2 搜索项目。
  • @MarcinJuraszek 是的,但我认为接受的答案可以处理任何一种情况(或者实际上使用 2 个键进行任何奇怪的匹配),但这就是为什么我说相关而不是重复。

标签: vb.net linq dictionary


【解决方案1】:

这是处理此问题的最佳方法,还是 .net 中有一些快速的“类似字典”的数据结构允许我为相同的数据拥有两个键?

没有提供两个键的内置数据结构,其中任何一个键都可以使用。

鉴于您想通过 either 键(而不是同时查找两者),使用封装两个 Dictionary(Of TKey, Of TValue) 的自定义类是有意义的,前提是存储两个字典的开销不是令人反感。

【讨论】:

  • 开销取决于您使用的类型。对于值的引用类型,它不应该那么大。
  • @MarcinJuraszek 是的,它不会很大——但它确实存在,这就是我提到它的原因。您正在这里进行内存速度权衡。
【解决方案2】:

您可以定义一个复合键,例如

Structure CKey
    Public Key1 As String
    Public Key2 As String
End Structure

以及使用该键的字典

Dim myDict As New Dictionary(Of CKey, String)

myDict.Add(New CKey() With {.Key1 = "key01", .Key2 = "key02"}, "Data0102")
myDict.Add(New CKey() With {.Key1 = "key11", .Key2 = "key12"}, "Data0103")
myDict.Add(New CKey() With {.Key1 = "key01", .Key2 = "key22"}, "Data0104")
myDict.Add(New CKey() With {.Key1 = "key11", .Key2 = "key22"}, "Data0105")

然后您可以运行一个简单的 LINQ 查询,例如:

Dim result = From el In myDict Where el.Key.Key1 = "key01" Select el

如果您不喜欢 LINQ,您仍然可以在自己的方法中循环遍历字典,自己检查键。

【讨论】:

  • 这将迭代您的字典(昂贵),而不是按照预期的方式使用它。
  • 能否详细说明其中的差异?
  • 当使用索引器在字典中查找项目时,例如dict[x],在内部它将使用哈希表来查找值,根据the documentation,这是一个O(1) 操作。您的建议涉及扫描字典中的所有键,直到找到正确的键,就执行成本而言,这是一个 O(n) 操作(最多可能需要 n 次迭代才能找到答案)。
  • 谢谢!这真的很有启发性
【解决方案3】:

我真的很惊讶我在这里得到了一个解决方案(因为我是这种编程的菜鸟)。

所以有两件事需要考虑:您需要知道您使用哪个键进行搜索,以及添加和删除条目。我想您可以通过共享子组件来添加和删除条目,甚至可以使用类(对它们了解不多)来克服这些问题。

也许有人可以对此进行改进。

我做到了,请参阅下面的部分;-]

    Dim myDict As New Dictionary(Of String, Double)
    Dim myKeyDict As New Dictionary(Of String, String)
    myDict.Add("key1", 5.5)
    myKeyDict.Add("key2", "key1")

    ' Access Dictionary with key1
    myDict("key1") = 7.7
    Debug.Print(CStr(myDict("key1")))

    ' Acces Dictionary with key2
    Dim thisKey1 As String = myKeyDict("key2")  ' retrieve key1 with the help of key2
    Debug.Print(CStr(myDict(thisKey1)))         ' Acces the actuall dictionary with the retrieved key 1

因此,我为字典创建了一个类,其中 key1 为字符串,key2 为字符串,val 为 double,具有基本的输入和输出操作:

Public Class MultiKeyDictonaryDbl
    Public DictVal As New Dictionary(Of String, Double)         ' key1=Variablenname, val=Wert
    Public DictKey1 As New Dictionary(Of String, String)        ' key1=In/Output-Variablenname (Textdatei), key2=Variablenname
    Public DictKey2 As New Dictionary(Of String, String)        ' key2=In/Output-Variablenname (Textdatei), key1=Variablenname
    Public length As Integer
    Public Sub Add(key1 As String, key2 As String, val As Double)
        DictVal.Add(key1, val)
        DictKey1.Add(key1, key2)
        DictKey2.Add(key2, key1)
    End Sub
    Public Sub Remove(key As String, id As Integer)
        Dim key1 As String = Nothing
        Dim key2 As String = Nothing
        Dim chk As Boolean
        If id = 1 Then
            key1 = key
            chk = DictKey1.TryGetValue(key1, key2)
        ElseIf id = 2 Then
            key2 = key
            chk = DictKey2.TryGetValue(key2, key1)
        End If
        If chk = True Then
            DictVal.Remove(key1)
            DictKey1.Remove(key1)
            DictKey2.Remove(key2)
        End If
    End Sub
    Public Function getValue(key As String, id As Integer) As Double
        Dim key1 As String = Nothing
        Dim key2 As String = Nothing
        Dim chk As Boolean
        If id = 1 Then
            key1 = key : chk = True
        ElseIf id = 2 Then
            key2 = key
            chk = DictKey2.TryGetValue(key2, key1)
        End If
        If chk = True Then
            chk = DictVal.TryGetValue(key1, getValue)
        End If
        If chk = False Then getValue = Double.PositiveInfinity
    End Function
    Public Function getList() As String(,)
        Dim val As Double
        Dim key1 As String = Nothing
        Dim key2 As String = Nothing
        Dim i As Integer = -1
        ' getLength in one line of code
        length = -1 : Dim l1 As Integer = DictVal.Count : Dim l2 As Integer = DictKey1.Count : Dim l3 As Integer = DictKey2.Count : If l1 = l2 And l2 = l3 Then length = l1
        If length < 1 Then Exit Function
        Dim List(length - 1, 2) As String
        For Each ele In DictKey2
            i += 1
            key2 = ele.Key : key1 = DictKey2(key2) : val = DictVal(key1)
            List(i, 0) = key1 : List(i, 1) = key2 : List(i, 2) = CStr(val)
        Next
        getList = List
    End Function
    Public Function getLength() As Integer
        getLength = -1
        Dim l1 As Integer = DictVal.Count
        Dim l2 As Integer = DictKey1.Count
        Dim l3 As Integer = DictKey2.Count
        If l1 = l2 And l2 = l3 Then getLength = l1
        length = getLength
    End Function
End Class

Sub testDictionaryVariablenVerarbeitung()
    ' some tests
    Dim testit As New MultiKeyDictonaryDbl
    testit.Add("Variablenname", "In/Output-Variablenname", 55.7)
    testit.Add("Variablenname2", "In/Output-Variablenname2", 90.7)
    Debug.Print(CStr(testit.getLength()))
    testit.Add("Blub", "dabdi", 916)
    testit.Remove("Variablenname", 1)

    Dim liste(,) As String = testit.getList
    Debug.Print(CStr(testit.getValue("Variablenname2", 1)))
    Debug.Print(CStr(testit.getValue("dabdi", 2)))
    Debug.Print(CStr(testit.getValue("dabdi", 1)))

End Sub

【讨论】:

    【解决方案4】:

    有点晚了,但是如何将 key1 与 key 2 连接起来:

    key1key2
    data
    

    这样,您始终可以轻松获取数据。您可以像这样添加:

     Public DictVal As New Dictionary(Of String, String)
    
      DictVal.Add(key1 & key2, value)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-08
      • 1970-01-01
      • 1970-01-01
      • 2011-07-15
      • 2010-12-02
      相关资源
      最近更新 更多