2011-11-19 11 views
7

Desde el previous question pregunté, RemoveAll es la forma más limpia de eliminar de List<> según una condición. Es curioso saber cuál es la mejor manera de eliminar de un LinkedList ya que no hay una función RemoveAll allí.Quitar de una lista vinculada

List<ItemClass> itemsToErase = new List<ItemClass>(); 
    foreach(ItemClass itm in DS) 
    { 
      if(itm.ToBeRemoved) 
       itemsToErase .Add(itm); 
    } 
    foreach(ItemClass eraseItem in itemsToErase) 
    { 
      DS.Remove(eraseItem); 
    }      

EDIT: DS es de tipo LinkedList<ItemClass>

Respuesta

23

Aunque no se puede eliminar nodos de un LinkedList<T> mientras que la iteración con foreach, que se pueden repetir manualmente el LinkedList<T> siguiendo la propiedad Next de cada LinkedListNode<T>. Sólo recuerda el siguiente nodo del nodo antes de extraerla:

var list = new LinkedList<int>(Enumerable.Range(0, 10)); 
var node = list.First; 
while (node != null) 
{ 
    var next = node.Next; 
    if (node.Value % 2 == 0) 
     list.Remove(node); 
    node = next; 
} 

Método de extensión:

public static int RemoveAll<T>(this LinkedList<T> list, Predicate<T> match) 
{ 
    if (list == null) 
    { 
     throw new ArgumentNullException("list"); 
    } 
    if (match == null) 
    { 
     throw new ArgumentNullException("match"); 
    } 
    var count = 0; 
    var node = list.First; 
    while (node != null) 
    { 
     var next = node.Next; 
     if (match(node.Value)) 
     { 
      list.Remove(node); 
      count++; 
     } 
     node = next; 
    } 
    return count; 
} 

Uso:

LinkedList<ItemClass> DS = ... 
DS.RemoveAll(itm => itm.ToBeRemoved); 

Ver también: Extension Methods (C# Programming Guide)

+0

Y si usa esto en más de un lugar, es un gran candidato para un método de extensión. – svick

+0

@svick: Buena idea; método de extensión agregado. – dtb

+0

Soy nuevo en el método de extensión. ¿Puede por favor cómo usar este método de extensión particular para mi caso? – devnull

0

La única manera de eliminar un elemento de System.Collections.Generic.LinkedList<T> es utilizar uno de los métodos Remove(). Sin embargo, esta operación es más rápida que eliminar un elemento del formulario List<T> (O(1) en lugar de O(n)), ya que la operación se puede realizar localmente. Los elementos detrás del artículo eliminado no se deben mover, solo los dos nodos antes y después del elemento eliminado deben vincularse entre sí. removed.Previous.Next = removed.Next; removed.Next.Previous = removed.Previous;. Esto se hace internamente, ya que las propiedades Previous y Next son de solo lectura.

+2

Mientras 'Remove (LinkedListNode )' es de hecho O (1), 'Remove (T)' es O (n), porque tiene que encontrar primero el elemento para eliminar. – svick

Cuestiones relacionadas