从列表

时间:2016-01-30 11:21:31

标签: vb.net algorithm pseudocode

我有一个列表,其中包含具有两个属性的数据行对象,Id和prentId。一个例子是这样的:

id    ParentId
130   -1
131   130
132   131
133   131
134   132
135   131
136   132
137   136
138   136
139   136
143   136

如果从层次结构的角度看待列表,它将如下所示:

130
    131
        132
            134
            136
                137
                138
                139
                143
        133
        135

我想要做的是创建一个算法,删除父项与特定ID匹配的所有元素和子元素。

例如,如果选择的ID为132,则应删除ID为132,134,136,137,138,139,143的元素。

到目前为止我尝试过的是这样的

    Private Function RemoveRecursive(ByRef values As List(Of DataRow), value As String) As List(Of DataRow)
        For index As Integer = values.Count - 1 To 0 Step -1
            If Not IsDBNull(values(index)("parent")) AndAlso values(index)("parent") = value Then
                values.RemoveAt(index)
                Return RemoveRecursive(values, value)
                value = values(index)("id")
            End If
        Next
        Return values
    End Function

4 个答案:

答案 0 :(得分:1)

我试图解决你的问题(c#):

private static void RemoveRecursive(List<DataRow> values, string valueToRemove) {
    DataRow itemToRemove = values.Find(dr => (string)dr["id"] == valueToRemove);
    values.Remove(itemToRemove);
    IEnumerable<string> children = values.Where(dr => (string)dr["ParentId"] == valueToRemove).Select(dr => (string)dr["id"]);
    foreach (string child in children)
        RemoveRecursive(values, child);
}

您可以这种方式调用此方法:

RemoveRecursive(values, "131");

您还可以添加一些空检查。

答案 1 :(得分:0)

我从所提供的数据中假设133和135还想要删除,因为他们是131的孩子?

达到你想要的一种方式可能是;

  • 创建标记为&#39;的空列表条目
  • 遍历您的列表,如果ParentID == 131或者ParentID在标记条目列表中,请将此节点添加到标记条目
  • 从原始数据集中删除所有已标记的对象

答案 2 :(得分:0)

你离我不远。你错过了两件事:

  1. 如果当前行的posts_categories (post_id, category_id) VALUES (?, ?)' with params [30, 1]: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '30-1' for key 'PRIMARY' 等于搜索值,则不仅仅是id
  2. 您在内部呼叫parent后设置重估值,因此它使用的值与初始值相同,即每次只检查RemoveRecursive
  3. 1号只需要扩展132语句。对于数字2,我会在删除行并将其传递给递归调用之前将当前id值存储在新变量中:

    if

    Working .NETFiddle

答案 3 :(得分:0)

可能证明有用的父/子的一般示例。这是乐观的,因为没有错误检查。请注意,Add和Remove方法都是重载的。

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim root As New PC(1)
    root.AddChild(1, 10)
    root.AddChild(1, 11)
    root.AddChild(1, 12)
    root.AddChild(11, 110)
    root.AddChild(11, 111)
    root.AddChild(110, 1100)
    root.AddChild(110, 1101)
    root.AddChild(1100, 11000)
    root.AddChild(1100, 11001)
    root.AddChild(1101, 11010)
    root.RemoveChild(1100)
End Sub

Class PC 'parent child
    Dim myID As Integer
    Dim parentPC As PC = Nothing
    Dim children As New List(Of PC)

    Public Sub New(ID As Integer)
        Me.myID = ID
    End Sub

    Public Function AddChild(parent As Integer, child As Integer) As PC
        Dim rv As PC
        rv = Me.AddChild(Me, parent, child)
        Return rv
    End Function

    Private Function AddChild(aPC As PC, parent As Integer, child As Integer) As PC
        Dim rv As PC
        Dim addPC As PC
        If aPC.myID = parent Then
            addPC = New PC(child)
            addPC.children = New List(Of PC)
            addPC.parentPC = aPC
            aPC.children.Add(addPC)
            Return addPC
        Else
            For Each chld As PC In aPC.children
                rv = chld.AddChild(chld, parent, child)
                If rv IsNot Nothing Then
                    Exit For
                End If
            Next
        End If
        Return rv
    End Function

    Public Function RemoveChild(child As Integer) As Boolean
        Dim rv As Boolean = False
        rv = Me.RemoveChild(child, Me)
        Return rv
    End Function

    Private Function RemoveChild(child As Integer, aPC As PC) As Boolean
        Dim rv As Boolean = False
        If aPC.myID = child Then
            For x As Integer = aPC.children.Count - 1 To 0 Step -1
                Dim chld As PC = aPC.children(x)
                Me.RemoveChild(chld.myID, chld)
            Next
            aPC.parentPC.children.Remove(aPC)
            aPC.children = Nothing
            aPC = Nothing
            rv = True
        Else
            For Each chld As PC In aPC.children
                rv = Me.RemoveChild(child, chld)
                If rv Then
                    Exit For
                End If
            Next
        End If
        Return rv
    End Function
End Class