2017-02-09 3 views
1

Ich habe die folgende KlasseC# Wie bestimmte Knoten aus der Liste entfernen

public class Item 
{ 
    public int Id { get; set; } 
    public int ParentId { get; set; } 
    public string Content { get; set; } 
    public bool IsLastItem { get; set; } 
} 

Lassen Sie sagen, ich das folgende Modell haben und ich möchte Elemente entfernen, die IsLastItem = false und nicht Kind haben. In diesem Szenario sollten item4 und item7 aus der Liste entfernt werden.

Model

erhalte ich die Liste meines Modells aus der Datenbank und ich simulierte es in dem Codeblock wie diese

var items = new List<Item> 
{ 
    new Item 
    { 
     Id = 1, 
     ParentId = 0, 
     Content = "item1", 
     IsLastItem = false 
    }, 
    new Item 
    { 
     Id = 2, 
     ParentId = 1, 
     Content = "item2", 
     IsLastItem = false 
    }, 
    new Item 
    { 
     Id = 3, 
     ParentId = 1, 
     Content = "item3", 
     IsLastItem = true 
    }, 
    new Item 
    { 
     Id = 4, 
     ParentId = 1, 
     Content = "item4", 
     IsLastItem = false 
    }, 
    new Item 
    { 
     Id = 5, 
     ParentId = 2, 
     Content = "item5", 
     IsLastItem = false 
    }, 
    new Item 
    { 
     Id = 6, 
     ParentId = 5, 
     Content = "item6", 
     IsLastItem = false 
    }, 
    new Item 
    { 
     Id = 7, 
     ParentId = 5, 
     Content = "item7", 
     IsLastItem = false 
    }, 
    new Item 
    { 
     Id = 8, 
     ParentId = 6, 
     Content = "item8", 
     IsLastItem = true 
    }, 
    new Item 
    { 
     Id = 9, 
     ParentId = 8, 
     Content = "item9", 
     IsLastItem = true 
    } 
}; 
+0

Möchten Sie sie durch ID oder alle Knoten ohne Kind entfernen? Wenn Sie alle Knoten ohne Kind entfernen möchten, warum entfernen Sie nicht auch Knoten 9? – osanger

+2

'var enumerable = items.Where (s =>! S.IsLastItem && items.All (t => t.ParentId! = S.Id)). ToList();' ??? – Aybe

+0

@ MichałZych: Benutzer können ein Modell erstellen, das item4 ist nicht das letzte Element, aber ich muss diese Knoten löschen. –

Antwort

5

Eine flache Liste wie diese ist nicht optimal für diese Art von Operationen - es schön sein könnte, wenn Sie die Liste wieder in einer Art Baumstruktur erhalten könnten (vielleicht ist es von SQL-Code zurückgeben FOR XML oder JSON verwenden, wenn Sie Anfang 2016, wo es einfacher wäre, den Baum zu überqueren.

auch zu beachten, dass, wie es ist, Ihre Beispieldaten setzt IsLastItem nicht ...

Wie ist, müssen Sie mindestens zweimal durchlaufen, so etwas wie dieses:

items.RemoveAll(x => x.IsLastItem == false && 
    items.Any(y => y.ParentId == x.Id) == false); 

Sie‘ sagen, um alle Elemente zu entfernen, wo IsLastItem falsch ist und wo es nicht mindestens ein Element gibt, dessen Eltern-ID die ID dieses Elements ist.

+0

Er ist Antwort entfernt item9, weil Sie in Ihrem simulierten Codeblock IsLastItem auf false für item9 setzen. Seine Lösung funktioniert gut. – LaggKing

2

Sie haben vergessen IsLastItem in Ihren verspottet Daten einzustellen, FYI. Sie sollten dies mit RemoveAll erreichen können.

public static void Main() 
{ 
    var items = init(); 
    items.RemoveAll(x => !items.Any(y => y.ParentId == x.Id) == true && x.IsLastItem == false);   

} 

public static List<Item> init() 
{   
    return new List<Item> 
    { 
     new Item 
     { 
      Id = 1, 
      ParentId = 0, 
      Content = "item1" 
     }, 
      new Item 
     { 
      Id = 2, 
      ParentId = 1, 
      Content = "item2" 
     }, 
      new Item 
     { 
      Id = 3, 
      ParentId = 1, 
      Content = "item3", 
      IsLastItem = true 
     }, 
      new Item 
     { 
      Id = 4, 
      ParentId = 1, 
      Content = "item4" 
     }, 
      new Item 
     { 
      Id = 5, 
      ParentId = 2, 
      Content = "item5" 
     }, 
      new Item 
     { 
      Id = 6, 
      ParentId = 5, 
      Content = "item6" 
     }, 
      new Item 
     { 
      Id = 7, 
      ParentId = 5, 
      Content = "item7" 
     }, 
      new Item 
     { 
      Id = 8, 
      ParentId = 6, 
      Content = "item8" 
     }, 
      new Item 
     { 
      Id = 9, 
      ParentId = 8, 
      Content = "item9", 
      IsLastItem = true 
     } 
    };  
} 
+0

Entschuldigung, ich habe vergessen, es zum Modell hinzuzufügen. Ich bearbeite nur die Frage :) –

1

Suchen Sie die ParentIds. Vergleichen Sie jedes Element mit der Liste der ParentId-Auflistung und überprüfen Sie IsLastitem.

var parents = items.Select(x => x.ParentId); 
items.RemoveAll(x => !parents.Contains(x.Id) && !x.IsLastItem); 
0

Ich würde vorschlagen, dass Sie eine baumartige Struktur zu verwenden, und eine Eigenschaft machen IsLastItem, die berechnet wird:

public class Item 
{ 
    public int Id { get; set; } 
    public string Content { get; set; } 
    public List<Item> SubItems { get; set; } 
    public bool IsLastItem { get { return SubItems.Count == 0; } } 
} 

Da die in der Datenbank gespeicherten Elemente wird eine flache Struktur haben, werden Sie muss eine Funktion schreiben, um den Baum aus der Datenbank zu erstellen (und den Baum bei Bedarf in die Datenbank schreiben), aber sobald das erledigt ist, wird der Baum einfacher zu bearbeiten sein.

Sie würden dann eine rekursive Funktion schreiben alle letzten Knoten zu entfernen, so etwas wie dieses:

List<Item> RemoveNodes(List<Item> tree) 
{ 
    var ret = tree.Where(item => !item.IsLastItem); 
    foreach (Item item in ret) 
    { 
     item.SubItems = RemoveNodes(item.SubItems); 
    } 
    return ret; 
} 

Das ist nicht gerade die beste Art und Weise, es zu tun sein kann, aber Sie bekommen die Idee.

Verwandte Themen