2012-01-26 25 views
6

Tengo una lista de la biblioteca de colecciones .NET y deseo eliminar un solo elemento. Tristemente, no puedo encontrarlo comparando directamente con otro objeto.Eliminar elemento de la lista con el predicado

Me temo que usar FindIndex y RemoveAt causará múltiples recorridos de la lista.

No sé cómo usar Enumerators para eliminar elementos, de lo contrario podría haber funcionado.

RemoveAll hace lo que necesito, pero no se detiene después de encontrar un elemento.

Ideas?

+0

¿Podría mostrar algún código de ejemplo? –

+0

La pregunta está etiquetada 'linked-list' pero la descripción sugiere' List '. ¿Cuál es? – Ani

+0

¿De qué tipo es su lista? – Strillo

Respuesta

1

EDIT: Ahora el PO ha cambiado para utilizar un LinkedList<T>, es fácil dar una respuesta que sólo repite la medida de lo que tiene que:

public static void RemoveFirst<T>(LinkedList<T> list, Predicate<T> predicate) 
{ 
    var node = list.First; 
    while (node != null) 
    { 
     if (predicate(node.Value)) 
     { 
      list.Remove(node); 
      return; 
     } 
     node = node.Next; 
    } 
} 
+0

Estoy buscando solo eliminar un solo elemento. – Steinbitglis

+0

@Steinbitglis: ¿Habrá múltiples valores que coincidan con el predicado? ¿Y qué tipo de lista estás usando? –

+0

@Steinbitglis: Editado para mostrar cómo puede usar un efecto secundario para usar 'RemoveAll'. –

2

Si desea eliminar únicamente la primera elemento que coincide con un predicado puede utilizar lo siguiente (ejemplo):

List<int> list = new List<int>(); 
list.Remove(list.FirstOrDefault(x => x = 10)); 

donde (x => x = 10) es, obviamente, su predicado para hacer coincidir los objetos.

+0

Esto requiere que la lista se enumere dos veces. Una vez para encontrar un elemento que coincida. Una vez para encontrar este elemento nuevamente en 'Eliminar'. –

+1

Es cierto que usar RemoveAt es más eficiente. – Strillo

10

List<T> tiene un método FindIndex que acepta un predicado

int index = words.FindIndex(s => s.StartsWith("x")); 
words.RemoveAt(index); 

Elimina primera palabra que empieza con "x". words se supone que es List<string> en este ejemplo.

+0

Si la lista tiene una búsqueda de índice de tiempo constante, creo que esto estará bien. Me preocupaba que RemoveAt también atravesara la lista. – Steinbitglis

+1

@Steinbitglis: Es una operación O (n), porque tiene que copiar todo. ¿Realmente * quieres * una lista vinculada? –

+0

Bueno, tengo muy pocos elementos, que siguen yendo y viniendo.Creo que al menos hashtable sería estúpido. No veo ningún problema con las listas vinculadas, aparte de esta optimización aparentemente trivial que no puedo entender. – Steinbitglis

Cuestiones relacionadas