2016-01-30 4 views
0

У меня есть список, содержащий объекты строк данных, которые имеют два атрибута: 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 

То, что я хотел бы сделать, это создать алгоритм, который удаляет все элементы и подэлементы, которые родители соответствуют конкретному идентификатору.

Например, если выбранный идентификатор равен 132, тогда элементы с идентификаторами 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 
+1

Я сделал это потому, что код может быть легко переведено с vb.net на C# и наоборот, и кроме того, так как C# и VB используют те же типы данных. (Вот переводчик http://converter.telerik.com/) – Andy

+0

Я понимаю, и я хорошо знаю об этом, но этот вопрос довольно общий, поэтому я подумал, что не будет проблемой также включать тег C#. Извините за неудобства ... – Andy

ответ

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"); 

Вы также можете добавить несколько нулевых проверок.

+0

Спасибо за сообщение. Я преобразовал ваш ответ на Vb, и я внесли необходимые изменения в соответствии с моей ситуацией. Я также добавил нулевую проверку и, похоже, работает. – Andy

0

Я предполагаю, что из данных, предоставленных, что 133 и 135 также хотят удалить, как они дети 131?

Один из способов достижения желаемого;

  • создать пустой список «меченые» записи
  • итерации по списку, если ParentID == 131 или ParentID находится в списке помеченных записей, добавьте этот узел в помеченных записи
  • Удалить все помеченные объекты из исходного набора данных
+0

Благодарим за предложение. Это похоже на то, как @romanoza подошла к этой ситуации. – Andy

0

Вы не за горами. Есть 2 вещи, которые вы пропустили:

  1. Если текущая строка имеет id равно значение поиска, а не только parent.
  2. Вы устанавливаете revalue после внутреннего вызова на RemoveRecursive, поэтому он использует то же значение, что и начальное, то есть он будет проверять только на 132.

Номер 1 просто требует продления вашего заявления if. Для номер 2, я бы просто сохранить текущее значение идентификатора в новую переменную перед удалением строки и передать, что рекурсивный вызов:

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 OrElse values(index)("id") = value) Then 
      Dim newValue as integer = values(index)("id").ToString() 
      values.RemoveAt(index) 
      RemoveRecursive(values, newValue) 
     End If 
    Next 
    Return values 
End Function 

Working .NETFiddle

0

общий пример родителя/ребенка, что может оказаться полезным , Это оптимистично, поскольку проверка ошибок отсутствует. Обратите внимание, что методы добавления и удаления перегружены.

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 
Смежные вопросы