我有一个列表,其中包含具有两个属性的数据行对象,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
答案 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的孩子?
达到你想要的一种方式可能是;
答案 2 :(得分:0)
你离我不远。你错过了两件事:
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
。parent
后设置重估值,因此它使用的值与初始值相同,即每次只检查RemoveRecursive
。 1号只需要扩展132
语句。对于数字2,我会在删除行并将其传递给递归调用之前将当前id值存储在新变量中:
if
答案 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