如何将第一个集合的项目属性与第二个集合中的项目链接起来

时间:2016-04-13 19:13:09

标签: vb.net collections

enter image description here

Dim stations As New Collection
            Dim trains As New Collection
            For i = 1 To 60
                Dim new_station As New station
                With new_station
                    .id = S_stationsDataSet.Node_Table.Rows(i - 1)(0)
                    .name = S_stationsDataSet.Node_Table.Rows(i - 1)(1)
                    .t = S_stationsDataSet.Node_Table.Rows(i - 1)(4)
                    .name_t = new_station.name & new_station.t
                    .x = S_stationsDataSet.Node_Table.Rows(i - 1)(2)
                    .y = S_stationsDataSet.Node_Table.Rows(i - 1)(3)
                End With
                stations.Add(new_station, new_station.name_t)
            Next   
            Dim a, c, l, n As String
            Dim m, b As Single
            For i = 1 To 78 Step 2
                a = S_trainsDataSet.T.Rows(1)(i)
                b = S_trainsDataSet.T.Rows(1)(i + 1)
                c = a & b
                l = S_trainsDataSet.T.Rows(2)(i)
                m = S_trainsDataSet.T.Rows(2)(i + 1)
                n = l & m
                Dim new_train As New train
                With new_train
                    .id = S_trainsDataSet.T.Rows(0)(i)
                    .src_t = S_trainsDataSet.T.Rows(1)(i + 1)
                    .dst_t = S_trainsDataSet.T.Rows(2)(i + 1)
                    .src = stations.Item(c)
                    .dst = stations.Item(n)
                End With
                trains.Add(new_train, new_train.id.ToString())
            Next

            For Each station In stations
                station.come = New Collection
                station.go = New Collection
                For Each train In trains
                    If train.src.name_t = station.name_t Then
                        station.go.add(train, train.id.ToString())
                    End If
                    If train.dst.name_t = station.name_t Then
                        station.come.add(train, train.id.ToString())
                    End If
                Next
            Next

vb:第1项中的项目的属性是第2个集合中的项目,反之亦然..当我删除项目时......在其他集合中它没有被更新为null

我们如何将两个馆藏的项目相互链接

1 个答案:

答案 0 :(得分:1)

经过漫长的等待,我终于有一段时间完成了这个。对于漫长的等待非常抱歉。

我不知道它是否完全符合您的要求,但它会使trainstation类更加协同工作。

由于您拥有如此多的馆藏(因为他们甚至在您的班级中),因此很难全部更新。我建议您使用Dictionary(Of TKey, TValue)并在train类中使用布尔属性。您的词典将如下所示:Dictionary(Of station, List(Of train))

首先,我们需要一些扩展方法,以便稍后帮助我们找到并遍历站点和列车。我们将从一个函数开始,通过指定它的名称找到一个电台。

创建一个新的Module并在以下位置添加此代码:

''' <summary>
''' Finds a station by it's name.
''' </summary>
''' <param name="StationCollection">The dictionary to look for the station in.</param>
''' <param name="Name">The name of the station to find.</param>
''' <remarks></remarks>
<System.Runtime.CompilerServices.Extension()> _
Public Function FindStationByName(ByRef StationCollection As Dictionary(Of station, List(Of train)), ByVal Name As String) As station
    Name = Name.ToLower() 'ToLower() provides case-insensitive checking.

    'Iterating through a Dictionary requires iterating through it's keys, as it's not index based.
    For Each k As station In StationCollection.Keys
        If k.name_t.ToLower() = Name Then
            Return k
        End If
    Next

    Return Nothing
End Function

然后我们需要通过它的id或它的名字来查找火车的扩展方法。我们还可以查找与特定车站相关的所有列车。在与上面相同的模块中添加:

''' <summary>
''' Finds a train by it's ID.
''' </summary>
''' <param name="TrainCollection">The list to look for the train in.</param>
''' <param name="Id">The ID of the train to find.</param>
''' <remarks></remarks>
<System.Runtime.CompilerServices.Extension()> _
Public Function FindTrainById(ByRef TrainCollection As List(Of train), ByVal Id As Integer) As train
    For Each t As train In TrainCollection
        If t.id = Id Then
            Return t
        End If
    Next

    Return Nothing
End Function

''' <summary>
''' Finds a train by it's name.
''' </summary>
''' <param name="TrainCollection">The list to look for the train in.</param>
''' <param name="TrainName">The name of the train to find.</param>
''' <remarks></remarks>
<System.Runtime.CompilerServices.Extension()> _
Public Function FindTrainByName(ByRef TrainCollection As List(Of train), ByVal TrainName As String) As train
    TrainName = TrainName.ToLower()

    For Each t As train In TrainCollection
        If t.name_t = TrainName Then
            Return t
        End If
    Next

    Return Nothing
End Function

''' <summary>
''' Finds all trains linked to the specified station.
''' </summary>
''' <param name="StationCollection">The dictionary to look for the station in.</param>
''' <param name="StationName">The name of the station which's trains to find.</param>
''' <remarks></remarks>
<System.Runtime.CompilerServices.Extension()> _
Public Function FindTrainsByStation(ByRef StationCollection As Dictionary(Of station, List(Of train)), ByVal StationName As String) As List(Of train)
    StationName = StationName.ToLower()

    For Each k As station In StationCollection.Keys
        If k.name_t.ToLower() = StationName Then
            Return StationCollection(k)
        End If
    Next

    Return Nothing
End Function

最后,我们需要一种扩展方法来从所有站点中移除火车。此扩展方法稍后将由RemoveAll()类中的RemoveAllByName()train方法使用。

''' <summary>
''' Removes a trains link from all stations.
''' </summary>
''' <param name="StationCollection">The dictionary of stations which's links to this train to remove.</param>
''' <param name="train">The train to remove.</param>
''' <param name="MatchName">If true, match by the train's name instead of it's ID.</param>
''' <remarks></remarks>
<System.Runtime.CompilerServices.Extension()> _
Public Sub RemoveTrainFromAllStations(ByVal StationCollection As Dictionary(Of station, List(Of train)), ByVal train As train, ByVal MatchName As Boolean)
    For Each k As station In StationCollection.Keys

        For i = 0 To StationCollection(k).Count - 1
            Dim t As train = StationCollection(k)(i)

            If MatchName = False Then 'Wether to match against the train's name or id.
                If t.id = train.id Then
                    t.Remove()
                End If

            Else
                If t.name_t = train.name_t Then
                    t.Remove()
                End If

            End If
        Next

    Next
End Sub

现在上课。

将词典引用传递给stationtrain类也可以帮助您创建检查哪些列车属于哪个站等的功能。通过这样做,您可以将这些类与词典一起使用,你甚至可以围绕这个做另一个包装类,以减少&#34;凌乱&#34;甚至更多。

您还需要覆盖EqualsGetHashCode方法,以便字典和哈希表能够正确查找您的密钥。

这只是示例代码,所以我在这里没有包含您的属性:

Public Class train
    Private StationCollection As Dictionary(Of station, List(Of train)) 'Storing the main dictionary.
    Private _parent As station

    ''' <summary>
    ''' Wether this train is departing or arriving.
    ''' </summary>
    ''' <remarks></remarks>
    Public Property Departing As Boolean = False

    ''' <summary>
    ''' The station that owns this train (multiple stations can own trains with the same names and IDs).
    ''' This is mainly used for internal functions.
    ''' </summary>
    ''' <remarks></remarks>
    Public ReadOnly Property ParentStation As station
        Get
            Return _parent
        End Get
    End Property



    ''' <summary>
    ''' Initializes a new instance of the train class.
    ''' </summary>
    ''' <param name="StationCollection">The main dictionary containing this train and it's station.</param>
    ''' <param name="ParentStation">The station that owns this train (multiple stations can own trains with the same names and IDs).</param>
    ''' <remarks></remarks>
    Public Sub New(ByRef StationCollection As Dictionary(Of station, List(Of train)), ByVal ParentStation As station)
        Me.StationCollection = StationCollection
        Me._parent = ParentStation
    End Sub



    ''' <summary>
    ''' Removes this train from it's station.
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub Remove()
        Me.StationCollection(ParentStation).Remove(Me)
    End Sub

    ''' <summary>
    ''' Removes this, and all other trains having the same ID as this, from all stations in the main dictionary.
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub RemoveAll()
        Me.StationCollection.RemoveTrainFromAllStations(Me, False)
    End Sub

    ''' <summary>
    ''' Removes this, and all other trains having the same name as this, from all stations in the main dictionary.
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub RemoveAllByName()
        Me.StationCollection.RemoveTrainFromAllStations(Me, True)
    End Sub


    'the rest of your code...


    'Overriding Equals() and GetHashCode(), comparison will be performed by comparing two trains' id's.
    Public Overrides Function Equals(obj As Object) As Boolean
        Return obj IsNot Nothing AndAlso obj.GetType() Is GetType(train) AndAlso DirectCast(obj, train).id = Me.id
    End Function

    Public Overrides Function GetHashCode() As Integer
        Return Me.id.GetHashCode()
    End Function
End Class

station类:

Public Class station
    Private StationCollection As Dictionary(Of station, List(Of train)) 'Linking this station to the main Dictionary.

    ''' <summary>
    ''' Gets a list of trains arriving at this station. Modifying the returned list will NOT affect the main dictionary or it's stations.
    ''' </summary>
    ''' <remarks></remarks>
    Public ReadOnly Property ArrivingTrains As List(Of train)
        Get
            Return Me.GetTrainsByType(False)
        End Get
    End Property

    ''' <summary>
    ''' Gets a list of trains departing from this station. Modifying the returned list will NOT affect the main dictionary or it's stations.
    ''' </summary>
    ''' <remarks></remarks>
    Public ReadOnly Property DepartingTrains As List(Of train)
        Get
            Return Me.GetTrainsByType(True)
        End Get
    End Property

    ''' <summary>
    ''' Gets all trains of the specified type that are linked to this station.
    ''' </summary>
    ''' <param name="Departing">Wether to get all departing trains or all arriving trains.</param>
    ''' <remarks></remarks>
    Private Function GetTrainsByType(ByVal Departing As Boolean) As List(Of train)
        Dim TrainList As List(Of train) = StationCollection(Me) 'Getting all trains for this station.
        Dim ReturnList As New List(Of train)

        For Each t As train In TrainList
            If t.Departing = Departing Then
                ReturnList.Add(t)
            End If
        Next

        Return ReturnList
    End Function

    ''' <summary>
    ''' Removes this station and all links to trains arriving or departing from it.
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub Remove()
        For Each t As train In StationCollection(Me) 'Iterate though all the trains for this station.
            GetType(train).GetField("_parent", Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic).SetValue(t, Nothing) 'Use reflection to set the train's parent to Nothing.
        Next

        StationCollection.Remove(Me)
    End Sub

    ''' <summary>
    ''' Initializes a new instance of the station class.
    ''' </summary>
    ''' <param name="StationCollection">The main dictionary containing this train and it's station.</param>
    ''' <remarks></remarks>
    Public Sub New(ByRef StationCollection As Dictionary(Of station, List(Of train)))
        Me.StationCollection = StationCollection
    End Sub

    'the rest of your code...

    'Overriding Equals() and GetHashCode(), comparison will be performed by comparing two stations' names.
    Public Overrides Function Equals(obj As Object) As Boolean
        Return obj IsNot Nothing AndAlso obj.GetType() Is GetType(station) AndAlso DirectCast(obj, station).name_t = Me.name_t
    End Function

    Public Overrides Function GetHashCode() As Integer
        Return Me.name_t.GetHashCode()
    End Function
End Class

添加新站/列车

在向字典中添加项目时,首先必须初始化新的station类,然后创建新的train类,将ParentStation参数指向刚刚创建的工作站

例如:

Dim MainDictionary As New Dictionary(Of station, List(Of train)) 'Create the dictionary (only do this once, unless you need multiple of course).

Dim new_station As New station(MainDictionary) 'Create a new station.
new_station.name = "Station 1"

MainDictionary.Add(new_station, New List(Of train))

Dim new_train As New train(MainDictionary, new_station) 'Create a new train.
new_train.id = 3
new_train.name_t = "Train 1"
new_train.Departing = True 'This train is leaving from the station.

MainDictionary(new_station).Add(new_train) 'Add the train to the station.

扩展方法

在......

时使用扩展方法
  • 您希望按名称找到特定的电台。

    例如:

    Dim st As station = MainDictionary.FindStationByName("Station 1")
    
  • 您想根据它的ID或名称查找火车。

    例如:

    Dim t As train = MainDictionary.FindStationByName("Station 1").ArrivingTrains.FindTrainById(3)
    Dim t2 As train = MainDictionary.FindStationByName("Station 1").ArrivingTrains.FindTrainByName("Train 1")
    
  • 或者当您想要从特定电台(按照其名称)获取所有列车时。

    例如:

    Dim trains As List(Of train) = MainDictionary.FindTrainsByStation("Station 1")
    

方法,字段和属性概述:

- train类 -

<强> StationCollection

  • 包含所有电台主词典引用的私人字段。

<强> _parent

  • 这列火车的私人油田是#34;链接&#34;到。

<强>出发

  • 指示该列车是否正在起飞(离开)或到达(即将到来)的公共财产

<强> ParentStation

  • 返回_parent
  • 值的公共只读属性

删除()

  • 将此列车从与其相关联的车站中移除。

<强>的removeAll()

  • 从主词典中的所有站点移除此列车以及所有其他具有相同ID的列车。

<强> RemoveAllByName()

  • RemoveAll()相同,但与列车匹配&#39;名字而不是他们的ID。

- station类 -

<强> StationCollection

  • train类相同。

<强> ArrivingTrains

  • 一个只读属性,返回所有到达(来到)此站的列车。

<强> DepartingTrains

  • 一个只读属性,返回从该站出发(离开)的所有列车。

<强> GetTrainsByType()

  • 获得到达/离开列车的私人方法。由上述属性使用。

删除()

  • 删除此电台以及主要字典中到达或离开列车的所有链接(通过使其_parent字段无效)。

希望这有帮助!很抱歉这么久。