2010-02-07 3 views
6

Ich habe eine LinkedList von Knoten, die jeweils eine LinkedList von Kanten speichern. Ich wollte etwas nach den LinienC#: Warum hat LinkedList keine RemoveAll-Methode, die ein Prädikat übernimmt?

nodes.RemoveAll(n => n.edges.Count == 0) 

tun, aber ohne RemoveAll geht das. Ich verstehe nicht, warum es es nicht hat, da andere Sammlungen es tun. Dies müsste auch alle Elemente durchlaufen und nur eins nach dem anderen entfernen, was ich verstehe, was für eine verkettete Liste nicht schlecht wäre.

Jetzt muss ich diese stattdessen tun:

for (LinkedListNode<MyNode> n2 = nodes.First; n2 != null;) 
{ 
    LinkedListNode<MyNode> temp = n2.Next; 
    if (n2.Value.edges.Count == 0) 
     nodes.Remove(n2); 
    n2 = temp; 
} 

Während es funktioniert, es macht die Dinge scheinen komplizierter als das, was sie sind.

+0

schon gefragt - http://stackoverflow.com/questions/133487/how-do-i-remove-elements-from-a-linkedlist-in-c-that-match- a-given-Kriterium – ChrisF

+2

@Chri sF: Nicht ganz dasselbe - diese Frage ging nur darum, ein Element zu entfernen, nicht alle Elemente. –

+0

Vielleicht wäre es schneller, eine neue LinkedList mit nur Edges.Count> 0 zu erstellen (anstatt all die Remove-Aktionen in der alten Liste auszuführen). Mark Byers Lösung unten tun. – Zyphrax

Antwort

8

Ich kann nicht sagen, warum diese Methode nicht existiert. Es scheint eine nützliche Methode zu sein. Sie können es mit einer Erweiterungsmethode selbst hinzufügen. Hier ist meine (wahrscheinlich schlecht, und nicht getestet) Versuch, das zu tun:

public static class LinkedListExtensions 
{ 
    public static void RemoveAll<T>(this LinkedList<T> linkedList, 
            Func<T, bool> predicate) 
    { 
     for (LinkedListNode<T> node = linkedList.First; node != null;) 
     { 
      LinkedListNode<T> next = node.Next; 
      if (predicate(node.Value)) 
       linkedList.Remove(node); 
      node = next; 
     } 
    } 
} 

Dann funktioniert das:

nodes.RemoveAll(n => n.edges.Count == 0); 

Alternativ können Sie das Kriterium invertieren, um die Elemente auszuwählen, die Sie behalten möchten und eine machen neue LinkedList von ihnen:

nodes = new LinkedList<MyNode>(nodes.Where(n => n.edges.Count != 0)); 
Verwandte Themen